cli dollcode encoder and decoder

add bigint to lib-porcelain

0xda157 09d07265 f9e68928

+80 -3
+7 -1
lib-porcelain/Cargo.toml
··· 1 1 [package] 2 2 name = "lib-porcelain" 3 - version = "0.2.0" 3 + version = "0.2.1" 4 4 license = "MIT" 5 5 authors = ["0xda157 <da157@voidq.com>"] 6 6 description = "dollcode encoder and decoder" 7 7 homepage = "https://codeberg.org/da157/porcelain" 8 8 repository = "https://codeberg.org/da157/porcelain" 9 9 edition = "2024" 10 + 11 + [dependencies] 12 + num = { version = "0.4.3", optional = true } 13 + 14 + [features] 15 + num = [ "dep:num" ]
+73 -2
lib-porcelain/src/lib.rs
··· 56 56 impl_std_Dollcode!(for u128); 57 57 impl_std_Dollcode!(for usize); 58 58 59 + #[cfg(feature = "num")] 60 + use num::{BigUint, ToPrimitive}; 61 + 62 + #[cfg(feature = "num")] 63 + impl Dollcode for BigUint { 64 + fn from_dollcode(input: &str) -> Option<Self> { 65 + let mut acc = BigUint::ZERO; 66 + 67 + for char in input.chars() { 68 + acc = acc * 3_u32 69 + + match char { 70 + '▖' => 1_u32, 71 + '▘' => 2_u32, 72 + '▌' => 3_u32, 73 + _ => return None, 74 + } 75 + } 76 + 77 + Some(acc) 78 + } 79 + 80 + fn to_dollcode(mut self) -> String { 81 + let mut res = String::new(); 82 + 83 + while self > BigUint::ZERO { 84 + self -= 1_u32; 85 + res.push( 86 + ['▖', '▘', '▌'][(self.clone() % 3_u32) 87 + .to_usize() 88 + .expect("failed to convert value to usize")], 89 + ); 90 + self /= 3_u32; 91 + } 92 + 93 + res.chars().rev().collect::<String>() 94 + } 95 + } 96 + 59 97 #[cfg(test)] 60 98 mod tests { 61 99 use crate::Dollcode; 62 100 63 101 #[test] 64 - fn test_encode() { 102 + fn std_encode() { 65 103 assert_eq!(0_u32.to_dollcode(), ""); 66 104 assert_eq!(1_u32.to_dollcode(), "▖"); 67 105 assert_eq!(2_u32.to_dollcode(), "▘"); ··· 77 115 } 78 116 79 117 #[test] 80 - fn test_decode() { 118 + fn std_decode() { 81 119 assert_eq!(u32::from_dollcode("invalid"), None); 82 120 assert_eq!(u32::from_dollcode("▖▌▌▌▌▖▖▖▘invalid"), None); 83 121 assert_eq!(u32::from_dollcode(""), Some(0)); ··· 91 129 assert_eq!( 92 130 u64::from_dollcode("▖▖▖▖▘▘▖▘▌▘▘▖▘▘▖▖▘▌▌▖▖▌▌▌▖▌▖▖▌▖▌▌▖▌▌▘▖▖▘▖▌"), 93 131 Some(u64::MAX) 132 + ); 133 + } 134 + 135 + #[test] 136 + #[cfg(feature = "num")] 137 + fn big_int_encode() { 138 + use num::BigUint; 139 + 140 + assert_eq!(BigUint::ZERO.to_dollcode(), ""); 141 + assert_eq!( 142 + BigUint::from_slice(&[893271]).to_dollcode(), 143 + "▖▖▘▘▌▘▌▌▘▘▘▌▌" 144 + ); 145 + assert_eq!( 146 + BigUint::from_slice(&[u32::MAX, u32::MAX, u32::MAX]).to_dollcode(), 147 + "▖▘▖▖▌▌▘▌▌▌▘▌▘▖▌▘▌▘▌▌▖▌▖▘▘▖▘▖▘▖▘▌▌▖▌▖▖▌▖▖▖▘▖▌▖▖▘▌▌▘▌▘▘▘▘▖▘▌▌▘▌" 148 + ); 149 + } 150 + 151 + #[test] 152 + #[cfg(feature = "num")] 153 + fn big_int_decode() { 154 + use num::BigUint; 155 + 156 + assert_eq!(BigUint::from_dollcode("invalid"), None); 157 + assert_eq!(BigUint::from_dollcode(""), Some(BigUint::ZERO)); 158 + assert_eq!( 159 + BigUint::from_dollcode("▖▖▘▘▌▘▌▌▘▘▘▌▌"), 160 + Some(BigUint::from_slice(&[893271])) 161 + ); 162 + assert_eq!( 163 + BigUint::from_dollcode("▖▘▖▖▌▌▘▌▌▌▘▌▘▖▌▘▌▘▌▌▖▌▖▘▘▖▘▖▘▖▘▌▌▖▌▖▖▌▖▖▖▘▖▌▖▖▘▌▌▘▌▘▘▘▘▖▘▌▌▘▌"), 164 + Some(BigUint::from_slice(&[u32::MAX, u32::MAX, u32::MAX])) 94 165 ); 95 166 } 96 167 }