# cj_common [![Rust](https://github.com/cubicle-jockey/cj_common/actions/workflows/rust.yml/badge.svg)](https://github.com/cubicle-jockey/cj_common/actions/workflows/rust.yml) [![Dependency Review](https://github.com/cubicle-jockey/cj_common/actions/workflows/dependency-review.yml/badge.svg)](https://github.com/cubicle-jockey/cj_common/actions/workflows/dependency-review.yml) [![Crate](https://img.shields.io/crates/v/cj_common.svg)](https://crates.io/crates/cj_common) [![API](https://docs.rs/cj_common/badge.svg)](https://docs.rs/cj_common) Collection of common functions used for other projects. Additional functionality added as more projects are spun up. Current features relate to: ```text * Base64 encoding/decoding * Hex encoding/decoding * Bit manipulation * In-set checking (values within a set of ranges) ``` cj_binary --- - b64 - structs, methods and traits for working with b64 encoding/decoding ```rust fn main() { use cj_common::prelude::*; let mut s2 = String::new(); for c in "Many hands make light work.".iter_to_b64() { s2.push(c); } assert_eq!(s2.as_str(), "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu"); } ``` ```rust fn main() { use cj_common::prelude::*; let mut v = Vec::new(); for b in "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu".iter_b64_to_byte() { v.push(b); } assert!(v.len() > 0); let r = String::from_utf8_lossy(v.as_slice()); let s = "Many hands make light work."; assert_eq!(r.to_string().as_str(), s); } ``` - hex - structs, methods and traits for working with hex encoding/decoding

Note that uppercase hex is the default output. Lowercase is supported too and most methods have a corresponding _low() implementation. For example, calling to_hex_be_low() instead of to_hex_be() will result in lowercase output ```rust fn main() { use cj_common::prelude::*; let x = 0x1F2i64; let s = x.to_hex_be(); x.to_hex_be_low(); let y: Option = i64::from_hex_be(s.as_str()); assert!(y.is_some()); assert_eq!(x, y.unwrap()); let x = 0x1F2i64; let s = x.to_hex_le(); let y: Option = i64::from_hex_le(s.as_str()); assert!(y.is_some()); assert_eq!(x, y.unwrap()); } ``` ```rust fn main() { use cj_common::prelude::*; let mut s = String::new(); for c in "Many hands make light work.".iter_to_hex() { s.push_str(c); } assert_eq!( s.as_str(), "4D616E792068616E6473206D616B65206C6967687420776F726B2E" ); let mut v = Vec::new(); for b in s.as_str().iter_hex_to_byte() { v.push(b); } let s2 = String::from_utf8_lossy(v.as_slice()).to_string(); assert_eq!(s2.as_str(), "Many hands make light work."); } ``` - bitbuf - structs, methods and traits for getting/setting bits at given positions of the implemented types ```rust fn main() { use cj_common::prelude::*; let x = 0b00000010u8; assert_eq!(x.get_bit(1), true); } ``` ```rust fn main() { use cj_common::prelude::*; let mut x = 0b00000000u8; x.set_bit(1, true); assert_eq!(x, 0b00000010u8); } ``` ```rust fn main() { use cj_common::prelude::*; let mut x = 0xABu8; let mut v = Vec::new(); for i in x.bit_iter() { v.push(i); } assert_eq!( v.as_slice(), &[true, true, false, true, false, true, false, true] ); } ``` ```rust fn main() { use cj_common::prelude::*; let x = vec![0xABu8, 0xAB, 0xAB]; let mut v = Vec::new(); for i in x.iter_to_bit() { v.push(i); } assert_eq!( v.as_slice(), &[ true, true, false, true, false, true, false, true, true, true, false, true, false, true, false, true, true, true, false, true, false, true, false, true ] ); let x = [2u128, 2, 2]; for i in x.as_slice().iter_to_bit().enumerate() { match i.0 { 1 | 129 | 257 => assert_eq!(i.1, true), _ => assert_eq!(i.1, false), } } } ``` ```rust fn main() { use cj_common::prelude::*; // mask examples let mask = 0b00011010u8; let byte = 0b01011010u8; assert_eq!(byte.matches_mask(&mask), true); assert_eq!(mask.as_mask_matches(&byte), true); let read_permission = 0b00000001u8; let write_permission = 0b00000010u8; let mod_permission = 0b00000100u8; let del_permission = 0b00001000u8; let full_permission = read_permission + write_permission + mod_permission + del_permission; let user = read_permission + write_permission; let moderator = user + mod_permission; let admin = full_permission; let fred = user; let jane = moderator; assert_eq!(fred.matches_mask(&read_permission), true); assert_eq!(fred.matches_mask(&write_permission), true); assert_eq!(fred.matches_mask(&moderator), false); assert_eq!(user.as_mask_matches(&jane), true); assert_eq!(admin.as_mask_matches(&jane), false); } ``` cj_helpers --- - in_set - structs, methods and traits for checking if values are within a given set of ranges. ```rust fn main() { use cj_common::prelude::*; assert_eq!('x'.in_range('a'..'z'), true); assert_eq!('z'.in_range_inclusive('a'..='z'), true); assert_eq!(1.in_range(1..3), true); assert_eq!( 'z'.in_set([('a'..'r').into(), ('r'..='z').into()].as_slice()), true ); let list = "lmnop"; for c in list.chars() { assert_eq!(c.in_range('k'..'q'), true); assert_eq!(c.in_set([('k'..'q').into()].as_slice()), true); 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 ); assert_eq!(c.in_range('w'..'z'), false); } let alpha_nums = [('a'..='z').into(), ('A'..='Z').into(), ('0'..='9').into()]; let list = "lmnop"; for c in list.chars() { assert_eq!(c.in_set(alpha_nums.as_slice()), true); } let list = [1_000, 10_000, 100_000_000]; for n in list { assert_eq!(n.in_range(1..200_000_000), true); assert_eq!(n.in_set([(1..200_000_000).into()].as_slice()), 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 ); assert_eq!(n.in_range(1_000_000_000..1_000_000_001), false); } assert_eq!('9'.is_ascii_numeric(), true); assert_eq!('T'.is_ascii_numeric(), false); assert_eq!('9'.is_ascii_alpha(), false); assert_eq!('T'.is_ascii_alpha(), true); for c in "9T".chars() { assert_eq!(c.is_ascii_alpha_numeric(), true); } } ```