cesrox/primitives/codes/
serial_number.rs1use std::str::FromStr;
2
3use crate::{conversion::from_bytes_to_text, derivation_code::DerivationCode, error::Error};
4
5#[derive(PartialEq, Eq, Debug)]
6pub struct SerialNumberCode;
7
8impl DerivationCode for SerialNumberCode {
9 fn hard_size(&self) -> usize {
10 2
11 }
12
13 fn soft_size(&self) -> usize {
14 0
15 }
16
17 fn value_size(&self) -> usize {
18 22
19 }
20
21 fn to_str(&self) -> String {
22 "0A".into()
23 }
24}
25
26impl FromStr for SerialNumberCode {
27 type Err = Error;
28
29 fn from_str(s: &str) -> Result<Self, Self::Err> {
30 let code = s.get(..2).ok_or(Error::EmptyCodeError)?;
31
32 match code {
33 "0A" => Ok(SerialNumberCode),
34 _ => Err(Error::UnknownCodeError),
35 }
36 }
37}
38
39pub fn pack_sn(sn: u64) -> String {
40 let payload_type = SerialNumberCode;
41 let sn_raw: Vec<u8> = sn.to_be_bytes().into();
42
43 let missing_zeros = payload_type.full_size() / 4 * 3 - payload_type.code_size() - sn_raw.len();
46 let sn_vec: Vec<u8> = std::iter::repeat(0)
47 .take(missing_zeros)
48 .chain(sn_raw)
49 .collect();
50 [
51 payload_type.to_str(),
52 from_bytes_to_text(&sn_vec)[2..].to_string(),
53 ]
54 .join("")
55}
56
57#[test]
58pub fn test_pack_sn() -> Result<(), Error> {
59 assert_eq!(pack_sn(1), "0AAAAAAAAAAAAAAAAAAAAAAB");
60 assert_eq!(pack_sn(64), "0AAAAAAAAAAAAAAAAAAAAABA");
61 assert_eq!(pack_sn(1000), "0AAAAAAAAAAAAAAAAAAAAAPo");
62
63 Ok(())
64}