pencil-box 0.1.6

A versatile Rust utility library, inspired by JavaScript's Lodash, providing common helper functions for collections, strings, numbers, and more, with no external dependencies.
Documentation

Pencil-Box

A simple and efficient Rust utility for:

  • ๐Ÿ“ฆ Splitting slices into fixed-size chunks with chunk
  • ๐Ÿ” Removing duplicate elements from vectors with uniq and uniq_performant
  • โž– Computing set differences between vectors with difference and difference_performant
  • ๐Ÿ—‘๏ธ Removing "empty" elements from vectors with compact

๐Ÿ“ฆ Installation

Add this to your Cargo.toml:

[dependencies]
pencil-box = "0.1.6"

Replace "0.1.6" with the latest version from crates.io


๐Ÿš€ Usage

โœ‚๏ธ Chunking Slices

use pencil_box::chunk;

fn main() {
    let data = vec![1, 2, 3, 4, 5];
    let result = chunk(&data, 2).unwrap();
    assert_eq!(result, vec![vec![1, 2], vec![3, 4], vec![5]]);
}

chunk Function Behavior

pub fn chunk<T: Clone>(array: &[T], chunk_size: usize) -> Result<Vec<Vec<T>>, &'static str>
  • โœ… Returns an error if chunk_size == 0
  • โœ… Returns an empty vector if the input slice is empty
  • โœ… Returns a single chunk if chunk_size >= array.len()
  • โœ… Returns multiple chunks of up to chunk_size elements otherwise

Each chunk is cloned into an owned Vec<T>.


๐Ÿ” Deduplicating Vectors

use pencil_box::{uniq, uniq_performant};

fn main() {
    let mut items = vec![1, 2, 2, 3, 1];
    uniq(&mut items); // or uniq_performant(&mut items);
    assert_eq!(items, vec![1, 2, 3]);
}

uniq Function Behavior

pub fn uniq<T: Eq + Hash + Clone>(values: &mut Vec<T>)
  • โœ… Uses the standard HashSet to remove duplicates in-place
  • โœ… Retains the first occurrence of each element
  • โœ… Preserves relative ordering
  • ๐Ÿ” Best for general-purpose use

uniq_performant Function Behavior

pub fn uniq_performant<T: Eq + Hash + Clone>(values: &mut Vec<T>)
  • ๐Ÿš€ Uses AHashSet for faster hashing and performance
  • โœ… Retains the first occurrence of each element
  • โœ… Preserves relative ordering
  • โšก Ideal for high-throughput or performance-critical use cases

โž– Computing Vector Differences

use pencil_box::{difference, difference_performant};

fn main() {
    let a = vec![1, 2, 3, 4];
    let b = vec![2, 4];
    let c = vec![5];
    let result = difference(&a, &vec![&b, &c]);
    // or: let result = difference_performant(&a, &vec![&b, &c]);
    assert_eq!(result, vec![1, 3]);
}

difference Function Behavior

pub fn difference<T: Eq + Hash + Clone>(to_compare: &Vec<T>, others: &Vec<&Vec<T>>) -> Vec<T>
  • โœ… Returns a new Vec<T> excluding any elements found in others
  • โœ… Uses standard HashSet for equality and lookup
  • โœ… Clones values into the output (fully owned)
  • โœ… Best for secure, general-purpose usage
  • โšก Preallocates memory for performance

difference_performant Function Behavior

pub fn difference_performant<T: Eq + Hash + Clone>(to_compare: &Vec<T>, others: &Vec<&Vec<T>>) -> Vec<T>
  • ๐Ÿš€ Uses AHashSet for faster lookup performance
  • โœ… Identical output to difference
  • โœ… Clones values for full ownership
  • โš ๏ธ Not cryptographically secure (faster but non-resistant to hash DoS attacks)
  • โšก Best for large or performance-critical data sets

๐Ÿ—‘๏ธ Compacting Vectors

use pencil_box::compact;

fn main() {
    let mut numbers = vec![1, 0, 2, 0, 3];
    compact(&mut numbers);
    assert_eq!(numbers, vec![1, 2, 3]);

    let mut strings = vec!["hello".to_string(), "".to_string(), "world".to_string()];
    compact(&mut strings);
    assert_eq!(strings, vec!["hello".to_string(), "world".to_string()]);
}

compact Function Behavior

pub fn compact<T: IsEmpty>(values: &mut Vec<T>)
  • ๐Ÿ—‘๏ธ Removes elements from a mutable vector that are considered "empty"
  • โœ… Modifies the vector in-place
  • โœ… Uses the IsEmpty trait for custom emptiness logic
  • โœ… Works with String, &str, Vec<T>, Option<T>, bool, integers, and floats
  • โšก Efficient: uses Vec::retain() under the hood

๐Ÿงช โœ… Running Tests

To run all unit tests

cargo test --tests

๐Ÿ”’ Safety

  • โœ… 100% safe Rust (#![forbid(unsafe_code)])
  • โœ… No unsafe blocks used
  • โœ… Pure functional logic

๐Ÿ“„ License


๐Ÿค Contributing

Contributions, bug reports, and feature requests are welcome.
Please open an issue or submit a pull request.


๐ŸŒ Links