1use std::collections::HashMap;
2use crate::util::unique;
3use crate::BaseCustom;
4use std::fmt;
5
6impl BaseCustom<u8> {
7
8 pub fn new(bytes: &[u8]) -> BaseCustom<u8> {
14 if bytes.iter().count() < 2 { panic!("Too few numeric units! Provide two or more.") }
15 let bytes = unique(bytes.to_vec());
16
17 let mut mapped = HashMap::with_capacity(bytes.iter().count());
18 for (i,b) in bytes.iter().enumerate() {
19 mapped.insert(*b, i as u8);
20 }
21
22 let count = bytes.iter().count() as u64;
23
24 BaseCustom::<u8> {
25 primitives: bytes,
26 primitives_hash: mapped,
27 base: count,
28 delim: None,
29 }
30 }
31
32 pub fn gen(&self, input_val: u64) -> Vec<u8> {
48 if input_val == 0 {
49 return vec![self.primitives[0]];
50 }
51 let mut number = input_val;
52 let mut result = Vec::new();
53 loop {
54 if number == 0 { break };
55 result.insert(0, self.primitives[(number % self.base) as usize]);
56 number = number/self.base;
57 };
58 result
59 }
60
61 pub fn decimal(&self, input_val: &[u8]) -> u64 {
77 input_val.iter().rev().enumerate().fold(0, |sum, (i, byt)|
78 sum + (self.primitives_hash[&byt] as u64) * self.base.pow(i as u32)
79 )
80 }
81
82 pub fn zero(&self) -> u8 {
84 self.primitives[0]
85 }
86
87 pub fn one(&self) -> u8 {
89 self.primitives[1]
90 }
91
92 pub fn nth(&self, pos: usize) -> Option<u8> {
97 if pos < self.base as usize {
98 Some(self.primitives[pos])
99 } else {
100 None
101 }
102 }
103}
104
105impl PartialEq for BaseCustom<u8> {
106 fn eq(&self, other: &BaseCustom<u8>) -> bool {
107 self.primitives == other.primitives &&
108 self.base == other.base &&
109 self.delim == other.delim
110 }
111}
112
113impl fmt::Debug for BaseCustom<u8> {
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
115 write!(f,
116 "BaseCustom\n\tprimitives: {:?}\n\tprimitives_hash: {:?}\n\tbase: {}\n\tdelim: {:?}",
117 self.primitives, self.primitives_hash, self.base, self.delim
118 )
119 }
120}