bytestream_rs/
logiclong.rs1use rand::{self, Rng};
2use regex::Regex;
3use std::fmt;
4
5#[derive(Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord)]
6pub struct LogicLong {
7 pub low: u32,
8 pub high: u32,
9 pub tag: String,
10}
11
12#[derive(Clone, Debug, PartialEq)]
13pub enum LogicLongError {
14 InvalidTag(String),
15}
16
17impl LogicLong {
18 pub fn new(low: u32, high: u32) -> LogicLong {
19 let mut logic_long = LogicLong {
20 low,
21 high,
22 tag: String::new(),
23 };
24 logic_long.tag = logic_long.to_tag();
25 logic_long
26 }
27
28 pub fn new_from_tag(tag: String) -> Result<LogicLong, LogicLongError> {
29 return LogicLong::from_tag(tag);
30 }
31
32 pub fn from_tag(tag: String) -> Result<LogicLong, LogicLongError> {
33 let arr: Vec<char> = vec![
34 '0', '2', '8', '9', 'P', 'Y', 'L', 'Q', 'G', 'R', 'J', 'C', 'U', 'V',
35 ];
36 let tag = LogicLong::fix_tag(tag);
37 let mut total: u64 = 0;
38 let base: u64 = 14;
39
40 for (i, c) in tag.replace("#", "").chars().rev().enumerate() {
42 let index = arr
44 .iter()
45 .position(|&x| x == c)
46 .ok_or_else(|| LogicLongError::InvalidTag(tag.clone()))?;
47 total += index as u64 * base.pow(i as u32);
49 }
50 Ok(LogicLong {
51 low: ((total % 256) as u32),
52 high: ((total / 256) as u32),
53 tag,
54 })
55 }
56
57 pub fn fix_tag(tag: String) -> String {
58 let re = Regex::new("[^A-Z0-9]+").unwrap();
59 "#".to_owned()
60 + &re
61 .replace_all(tag.to_uppercase().as_str(), "")
62 .replace("O", "0")
63 }
64
65 pub fn random() -> LogicLong {
66 let mut rng = rand::thread_rng();
67 let low = rng.gen_range(0..100);
68 let high = rng.gen::<u32>();
69 LogicLong::new(low, high)
70 }
71
72 pub fn to_tag(&self) -> String {
73 let arr: Vec<char> = vec![
74 '0', '2', '8', '9', 'P', 'Y', 'L', 'Q', 'G', 'R', 'J', 'C', 'U', 'V',
75 ];
76 let mut tag = String::new();
77 let mut total = self.low as i64 + self.high as i64 * 0x100;
78 let mut b14;
79
80 while total != 0 {
81 b14 = total % 14;
82 total /= 14;
83 tag.insert(0, arr[b14 as usize]);
84 }
85 LogicLong::fix_tag(tag)
86 }
87
88 }
116
117impl fmt::Display for LogicLong {
118 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
119 write!(f, "{} ({}, {})", self.to_tag(), self.low, self.high)
120 }
121}