Skip to content

Get your functions running, Head out on the mainframe, Lookin' for extension, And whatever comes our way -- Born to be Common.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE_APACHE
MIT
LICENSE_MIT
Notifications You must be signed in to change notification settings

cubicle-jockey/cj_common

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

cj_common

Rust Dependency Review Crate API

A comprehensive Rust library providing essential utilities for encoding, bit manipulation, and data validation. This crate offers high-performance implementations of commonly needed functionality with both direct conversion methods and efficient iterator-based approaches.

Features

  • πŸ” Base64 Encoding/Decoding - Complete Base64 support with string conversion and streaming iterators
  • πŸ”’ Hexadecimal Encoding/Decoding - Full hex support with uppercase/lowercase options and iterator interfaces
  • ⚑ Bit Manipulation - Efficient bit-level operations with get/set functionality and bit iteration
  • πŸ“Š Range Validation - Flexible in-set checking for values within ranges, slices, and collections
  • πŸš€ High Performance - Optimized implementations with zero-copy iterators where possible
  • πŸ”§ Easy Integration - Simple prelude module for importing all functionality

Installation

Add this to your Cargo.toml:

[dependencies]
cj_common = "1.1.0"

For async channel functionality, enable the channel feature:

[dependencies]
cj_common = { version = "1.1.0", features = ["channel"] }

Quick Start

The easiest way to get started is by importing the prelude module:

use cj_common::prelude::*;

fn quick_start_example() {
    // Base64 encoding
    let encoded = "Hello, World!".to_b64_string();
    println!("Encoded: {}", encoded);

    // Base64 decoding
    if let Some(decoded_bytes) = b64_to_bytes(&encoded) {
        let decoded = String::from_utf8_lossy(&decoded_bytes);
        println!("Decoded: {}", decoded);
    }

    // Hex encoding
    let mut hex_string = String::new();
    for hex_pair in "Hello".iter_to_hex() {
        hex_string.push_str(hex_pair);
    }
    println!("Hex: {}", hex_string);

    // Bit manipulation
    let mut value = 0u8;
    value.set_bit(3, true);  // Set bit 3
    assert_eq!(value.get_bit(3), true);

    // Range checking
    assert_eq!('m'.in_range('a'..'z'), true);
}

API Documentation

πŸ” Base64 (cj_binary::b64)

Complete Base64 encoding and decoding with multiple approaches:

Direct Conversion

use cj_common::prelude::*;

fn base64_direct_conversion_example() {
    // String to Base64
    let encoded = "Many hands make light work.".to_b64_string();
    assert_eq!(encoded, "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu");

    // Base64 to bytes
    if let Some(decoded) = b64_to_bytes("TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu") {
        let text = String::from_utf8_lossy(&decoded);
        assert_eq!(text, "Many hands make light work.");
    }
}

Iterator-Based Approach

use cj_common::prelude::*;

fn base64_iterator_example() {
    // Encode using iterator
    let mut encoded = String::new();
    for c in "Many hands make light work.".iter_to_b64() {
        encoded.push(c);
    }
    assert_eq!(encoded, "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu");

    // Decode using iterator
    let mut decoded = Vec::new();
    for byte in "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu".iter_b64_to_byte() {
        decoded.push(byte);
    }
    let text = String::from_utf8_lossy(&decoded);
    assert_eq!(text, "Many hands make light work.");
}

πŸ”’ Hexadecimal (cj_binary::hex)

Flexible hexadecimal encoding and decoding with case options:

Note: Uppercase hex is the default output. Most methods have a corresponding _low() variant for lowercase output (e.g., to_hex_be_low() instead of to_hex()).

Basic Usage

use cj_common::prelude::*;

fn hex_basic_usage_example() {
    // String to hex
    let mut hex = String::new();
    for hex_pair in "Hello".iter_to_hex() {
        hex.push_str(hex_pair);
    }
    println!("Hex: {}", hex);

    // Numeric values
    let value = 0x1F2i64;
    let hex_be = value.to_hex_be();      // Big-endian
    let hex_le = value.to_hex_le();      // Little-endian
    let hex_be_low = value.to_hex_be_low(); // Lowercase
}

Iterator-Based Approach

use cj_common::prelude::*;

fn hex_iterator_example() {
    // Encode using iterator
    let mut hex_string = String::new();
    for hex_pair in "Many hands make light work.".iter_to_hex() {
        hex_string.push_str(hex_pair);
    }
    assert_eq!(hex_string, "4D616E792068616E6473206D616B65206C6967687420776F726B2E");

    // Decode using iterator
    let mut decoded = Vec::new();
    for byte in "4D616E792068616E6473206D616B65206C6967687420776F726B2E".iter_hex_to_byte() {
        decoded.push(byte);
    }
    let text = String::from_utf8_lossy(&decoded);
    assert_eq!(text, "Many hands make light work.");
}

⚑ Bit Manipulation (cj_binary::bitbuf)

Efficient bit-level operations with comprehensive functionality:

Basic Bit Operations

use cj_common::prelude::*;

fn basic_bit_operations_example() {
    // Get and set individual bits
    let x = 0b00000010u8;
    assert_eq!(x.get_bit(1), true);

    let mut x = 0b00000000u8;
    x.set_bit(1, true);
    assert_eq!(x, 0b00000010u8);
}

Bit Iteration

use cj_common::prelude::*;

fn bit_iteration_example() {
    // Iterate over bits in a single value
    let x = 0xABu8;
    let mut bits = Vec::new();
    for bit in x.bit_iter() {
        bits.push(bit);
    }
    assert_eq!(bits, [true, true, false, true, false, true, false, true]);

    // Iterate over bits in a collection
    let data = vec![0xABu8, 0xAB, 0xAB];
    let mut all_bits = Vec::new();
    for bit in data.iter_to_bit() {
        all_bits.push(bit);
    }
    // Results in 24 bits total (3 bytes Γ— 8 bits each)
}

Advanced Bit Operations

use cj_common::prelude::*;

fn advanced_bit_operations_example() {
    // Work with different integer types
    let x = [2u128, 2, 2];
    for (index, bit) in x.as_slice().iter_to_bit().enumerate() {
        match index {
            1 | 129 | 257 => assert_eq!(bit, true),  // Bit position 1 in each u128
            _ => assert_eq!(bit, false),
        }
    }
}

πŸ“Š Range Validation (cj_helpers::in_set)

Flexible validation for checking if values exist within specified ranges or collections:

Basic Range Checking

use cj_common::prelude::*;

fn basic_range_checking_example() {
    // Simple range checking
    assert_eq!('m'.in_range('a'..'z'), true);
    assert_eq!(15.in_range(10..20), true);
    assert_eq!(25.in_range(10..20), false);
}

Complex Set Validation

use cj_common::prelude::*;

fn complex_set_validation_example() {
    // Character validation with multiple criteria
    let test_chars = "lmnop";
    for c in test_chars.chars() {
        assert_eq!(c.in_range('k'..'q'), true);

        // Check against multiple sets
        assert_eq!(
            c.in_set([
                ('k'..='l').into(),                // RangeInclusive
                ('m'..'n').into(),                 // Range
                ('n'..='p').into(),                // RangeInclusive
                ['a', 'b', 'c'].as_slice().into(), // Slice
                "test123".into(),                  // str
            ].as_slice()),
            true
        );
    }

    // Numeric validation
    let numbers = [1_000, 10_000, 100_000_000];
    for n in numbers {
        assert_eq!(n.in_range(1..200_000_000), true);

        assert_eq!(
            n.in_set([
                (1..=10).into(),                 // RangeInclusive
                (500..2_000).into(),             // Range
                (9_999..=100_000_000).into(),    // RangeInclusive
                [30, 90, 700].as_slice().into()  // Slice
            ].as_slice()),
            true
        );
    }
}

Performance

This crate is designed with performance in mind:

  • Zero-copy iterators where possible to minimize memory allocations
  • Optimized algorithms for encoding/decoding operations
  • Efficient bit manipulation using native CPU instructions
  • Minimal dependencies to reduce compilation time and binary size

Benchmarks

This crate includes comprehensive benchmarks to measure performance across all major functionality. The benchmarks cover:

  • Base64 encoding/decoding - Both direct conversion and iterator-based approaches
  • Hex encoding/decoding - String and binary data with various sizes
  • Bit manipulation - Get/set operations and bit iteration across different integer types
  • Range validation - Simple range checks and complex set operations

Running Benchmarks

To run the benchmarks:

cargo bench

This will generate detailed performance reports and HTML output (if available) showing timing comparisons across different operations and data sizes.

Benchmark Results

The benchmarks test various scenarios including:

  • Small vs. large data sets
  • String vs. binary data encoding
  • Direct function calls vs. iterator-based processing
  • Different integer types for bit operations

Results are displayed with statistical analysis including confidence intervals and outlier detection.

License

This project is licensed under either of

at your option.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Links

About

Get your functions running, Head out on the mainframe, Lookin' for extension, And whatever comes our way -- Born to be Common.

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE_APACHE
MIT
LICENSE_MIT

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages