1use std::str::FromStr;
2
3use crate::{
4 conversion::{adjust_with_num, b64_to_num},
5 derivation_code::DerivationCode,
6 error::Error,
7};
8
9#[derive(Debug, PartialEq, Eq)]
10pub enum GroupCode {
11 IndexedControllerSignatures(u16),
12 IndexedWitnessSignatures(u16),
13 NontransferableReceiptCouples(u16),
14 SealSourceCouples(u16),
16 FirstSeenReplyCouples(u16),
17 TransferableIndexedSigGroups(u16),
18 LastEstSignaturesGroups(u16),
19 Frame(u16),
20 #[cfg(feature = "cesr-proof")]
21 PathedMaterialQuadruple(u16),
22}
23
24impl DerivationCode for GroupCode {
25 fn value_size(&self) -> usize {
26 0
27 }
28
29 fn soft_size(&self) -> usize {
30 2
31 }
32
33 fn hard_size(&self) -> usize {
34 2
35 }
36
37 fn to_str(&self) -> String {
38 let (code, count) = match self {
39 GroupCode::IndexedControllerSignatures(count) => ("-A", count),
40 GroupCode::IndexedWitnessSignatures(count) => ("-B", count),
41 GroupCode::NontransferableReceiptCouples(count) => ("-C", count),
42 GroupCode::FirstSeenReplyCouples(count) => ("-E", count),
43 GroupCode::TransferableIndexedSigGroups(count) => ("-F", count),
44 GroupCode::SealSourceCouples(count) => ("-G", count),
45 GroupCode::LastEstSignaturesGroups(count) => ("-H", count),
46 GroupCode::Frame(len) => ("-V", len),
47 #[cfg(feature = "cesr-proof")]
48 GroupCode::PathedMaterialQuadruple(len) => ("-L", len),
49 };
50 [code, &adjust_with_num(count.to_owned(), self.soft_size())].join("")
51 }
52}
53
54impl FromStr for GroupCode {
55 type Err = Error;
56
57 fn from_str(s: &str) -> Result<Self, Self::Err> {
58 let code = s.get(..2).ok_or(Error::EmptyCodeError)?;
59 let count_part = s.get(2..4).ok_or(Error::EmptyCodeError)?;
60 let count = b64_to_num(count_part.as_bytes())?;
61 match code {
62 "-A" => Ok(Self::IndexedControllerSignatures(count)),
63 "-B" => Ok(Self::IndexedWitnessSignatures(count)),
64 "-C" => Ok(Self::NontransferableReceiptCouples(count)),
65 "-D" => todo!(),
66 "-E" => Ok(Self::FirstSeenReplyCouples(count)),
67 "-F" => Ok(Self::TransferableIndexedSigGroups(count)),
68 "-H" => Ok(Self::LastEstSignaturesGroups(count)),
70 "-G" => Ok(Self::SealSourceCouples(count)),
72 #[cfg(feature = "cesr-proof")]
74 "-L" => Ok(Self::PathedMaterialQuadruple(count)),
75 "-U" => todo!(),
76 "-V" => Ok(Self::Frame(count)),
77 "-W" => todo!(),
78 "-X" => todo!(),
79 "-Y" => todo!(),
80 "-Z" => todo!(),
81 _ => Err(Error::UnknownCodeError),
82 }
83 }
84}
85
86#[test]
87pub fn test_group_codes_to_str() -> Result<(), Error> {
88 assert_eq!(GroupCode::IndexedControllerSignatures(3).to_str(), "-AAD");
89 assert_eq!(GroupCode::IndexedWitnessSignatures(30).to_str(), "-BAe");
90 assert_eq!(
91 GroupCode::NontransferableReceiptCouples(100).to_str(),
92 "-CBk"
93 );
94 assert_eq!(GroupCode::FirstSeenReplyCouples(127).to_str(), "-EB_");
95 assert_eq!(
96 GroupCode::TransferableIndexedSigGroups(4095).to_str(),
97 "-F__"
98 );
99 assert_eq!(GroupCode::SealSourceCouples(0).to_str(), "-GAA");
100 assert_eq!(GroupCode::Frame(1000).to_str(), "-VPo");
101 Ok(())
102}
103
104#[test]
105pub fn test_group_codes_from_str() -> Result<(), Error> {
106 assert_eq!(GroupCode::IndexedControllerSignatures(3), "-AAD".parse()?);
107 assert_eq!(GroupCode::IndexedWitnessSignatures(30), "-BAe".parse()?);
108 assert_eq!(
109 GroupCode::NontransferableReceiptCouples(100),
110 "-CBk".parse()?
111 );
112 assert_eq!(GroupCode::FirstSeenReplyCouples(127), "-EB_".parse()?);
113 assert_eq!(
114 GroupCode::TransferableIndexedSigGroups(4095),
115 "-F__".parse()?
116 );
117 assert_eq!(GroupCode::SealSourceCouples(0), "-GAA".parse()?);
118 assert_eq!(GroupCode::Frame(1000), "-VPo".parse()?);
119 Ok(())
120}