1#[cfg(test)]
2mod tests;
3
4mod parser;
5
6use parser::{parse_token, parse_token_id};
7use std::fmt;
8use std::fmt::{Display, Formatter};
9use std::iter::repeat_with;
10use std::rc::Rc;
11use rand::thread_rng;
12use rand::Rng;
13
14const RADIX : u32 = 32;
16
17#[derive(Copy)]
19#[derive(Debug)]
20pub struct Token {
21 value : u32
22}
23
24#[derive(Debug)]
26pub struct TokenId {
27 tokens : Rc<Box<[Token]>>
28}
29
30impl Token {
31 pub fn new() -> Self {
33 Self::create(thread_rng().gen())
34 }
35
36 pub fn create(value : u32) -> Self {
38 Token {
39 value : value
40 }
41 }
42
43 pub fn decode(token : &str) -> Result<Self, &str> {
45 parse_token(token)
46 }
47
48 pub fn get_value(&self) -> u32 {
50 self.value
51 }
52
53 pub fn encode(&self) -> String {
55 let mask : u64 = 0b11111;
56 let block : u64 = self.block();
57
58 let iter = [30,25,20,15,10,5,0].into_iter()
59 .map(|bits| char::from_digit((block >> bits & mask).try_into().unwrap(),RADIX).unwrap());
60
61 String::from_iter(iter)
62 }
63
64 fn block(&self) -> u64 {
66 (u64::from(self.checksum()) << 32)
67 + u64::from(self.value)
68 }
69
70 fn checksum(&self) -> u32 {
72 let mask : u32 = 0b111;
73
74 (0..11).into_iter()
75 .map(|i| self.value >> i*3 & mask)
76 .reduce(|c1,c2| c1 ^ c2)
77 .expect("build checksum")
78 }
79}
80
81impl TokenId {
82 pub fn new_64() -> Self {
84 Self::new(2)
85 }
86
87 pub fn new_128() -> Self {
89 Self::new(4)
90 }
91
92 pub fn new_256() -> Self {
94 Self::new(8)
95 }
96
97 pub fn new(token_len : usize) -> Self {
99 let token : Vec<Token> = repeat_with(|| Token::new()).take(token_len).collect();
100
101 Self::create(token.into_boxed_slice())
102 }
103
104 pub fn create(tokens : Box<[Token]>) -> Self {
106 TokenId {
107 tokens : Rc::new(tokens)
108 }
109 }
110
111 pub fn decode(tokenid : &str) -> Result<Self,&str> {
113 parse_token_id(tokenid)
114 }
115
116 pub fn get_tokens(&self) -> Vec<Token> {
118 self.tokens.into_iter()
119 .map(|b| *b)
120 .collect()
121 }
122
123 pub fn get_values(&self) -> Vec<u32> {
125 self.tokens.into_iter()
126 .map(|t| t.get_value())
127 .collect()
128 }
129
130 fn encode(&self) -> String {
132 self.tokens.into_iter()
133 .map(|t| t.encode())
134 .reduce(|s1,s2| s1 + "-" + &s2)
135 .unwrap()
136 }
137}
138
139impl Clone for Token {
140 fn clone(&self) -> Token {
141 *self
142 }
143}
144
145impl Clone for TokenId {
146 fn clone(&self) -> Self {
147 Self {
148 tokens : self.tokens.clone()
149 }
150 }
151}
152
153impl Default for Token {
154 fn default() -> Self {
155 Self::create(0)
156 }
157}
158
159impl Into<u32> for Token {
160 fn into(self) -> u32 {
161 self.value
162 }
163}
164
165impl Into<String> for Token {
166 fn into(self) -> String {
167 self.encode()
168 }
169}
170
171impl Into<String> for TokenId {
172 fn into(self) -> String {
173 self.encode()
174 }
175}
176
177impl From<u32> for Token {
178 fn from(value : u32) -> Self {
179 Self::create(value)
180 }
181}
182
183impl Display for Token {
210 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
211 write!(f, "{}", self.encode())
212 }
213}
214
215impl Display for TokenId {
216 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
217 write!(f, "{}", self.encode())
218 }
219}