coc_rs/util/
logic_long_to_code_converter_util.rs1use super::LogicLong;
2
3#[derive(Debug)]
4pub struct LogicLongToCodeConverterUtil {
5 hash_tag: String,
6 conversion_chars: String,
7}
8
9impl LogicLongToCodeConverterUtil {
10 pub fn new(hash_tag: &str, conversion_chars: &str) -> Self {
11 Self { hash_tag: hash_tag.to_string(), conversion_chars: conversion_chars.to_string() }
12 }
13
14 pub fn to_code(&self, logic_long: LogicLong) -> String {
15 let high_value = i64::from(logic_long.get_higher_int());
16
17 if high_value < 256 {
18 return self.hash_tag.clone()
19 + &self.convert((i64::from(logic_long.get_lower_int()) << 8) | high_value);
20 }
21
22 #[cfg(feature = "tracing")]
23 tracing::trace!("Cannot convert the code to string. Higher int value too large");
24 String::new()
25 }
26
27 pub fn to_id(&self, code: &str) -> LogicLong {
28 if code.len() < 14 {
29 let id_code = code.replace(self.hash_tag.as_str(), "");
30 let id = self.convert_code(&id_code);
31
32 if id != -1 {
33 return LogicLong::new((id % 256) as i32, ((id >> 8) & 0x7FFF_FFFF) as i32);
34 }
35 } else {
36 #[cfg(feature = "tracing")]
37 tracing::trace!("Cannot convert the string to code. String is too long.");
38 }
39
40 LogicLong::new(-1, -1)
41 }
42
43 pub fn convert_code(&self, code: &str) -> i64 {
44 let mut id: i64 = 0;
45 let conversion_chars_count = self.conversion_chars.len();
46 let code_chars_count = code.len();
47
48 for i in 0..code_chars_count {
49 let char_index = self.conversion_chars.find(code.chars().nth(i).unwrap());
50
51 if char_index.is_none() {
52 #[cfg(feature = "tracing")]
53 tracing::trace!(
54 "Cannot convert the string to code. String contains invalid character(s)."
55 );
56 id = -1;
57 break;
58 }
59
60 id = id * conversion_chars_count as i64 + char_index.unwrap() as i64;
61 }
62
63 id
64 }
65
66 fn convert(&self, mut value: i64) -> String {
67 if value > -1 {
68 let conversion_chars_count = self.conversion_chars.len();
69 let mut code = [' '; 12];
70
71 for i in (0..12).rev() {
72 let Ok(index) = usize::try_from(value % conversion_chars_count as i64) else {
73 #[cfg(feature = "tracing")]
74 tracing::trace!(
75 "LogicLongToCodeConverter: value to convert ({}) cannot be negative!",
76 value
77 );
78
79 return String::new();
80 };
81 if let Some(char) = self.conversion_chars.get(index..=index) {
82 code[i] = char.chars().next().unwrap();
83 }
84 value /= conversion_chars_count as i64;
85
86 if value == 0 || i == 0 {
87 let start_idx = code.iter().take_while(|&&c| c == ' ').count();
88 let mut result = String::with_capacity(12 - start_idx);
89 for ch in &code[start_idx..] {
90 result.push(*ch);
91 }
92 return result;
93 }
94 }
95 }
96
97 #[cfg(feature = "tracing")]
98 tracing::trace!("LogicLongToCodeConverter: value to convert cannot be negative");
99
100 String::new()
101 }
102}