snarkvm_console_program/data/identifier/
mod.rs1mod bytes;
17mod equal;
18mod from_bits;
19mod from_field;
20mod parse;
21mod serialize;
22mod size_in_bits;
23mod to_bits;
24mod to_field;
25
26use snarkvm_console_network::Network;
27use snarkvm_console_types::{Field, prelude::*};
28
29#[derive(Copy, Clone)]
39pub struct Identifier<N: Network>(Field<N>, u8); impl<N: Network> From<&Identifier<N>> for Identifier<N> {
42 fn from(identifier: &Identifier<N>) -> Self {
44 *identifier
45 }
46}
47
48impl<N: Network> TryFrom<String> for Identifier<N> {
49 type Error = Error;
50
51 fn try_from(identifier: String) -> Result<Self> {
53 Self::from_str(&identifier)
54 }
55}
56
57impl<N: Network> TryFrom<&String> for Identifier<N> {
58 type Error = Error;
59
60 fn try_from(identifier: &String) -> Result<Self> {
62 Self::from_str(identifier)
63 }
64}
65
66impl<N: Network> TryFrom<&str> for Identifier<N> {
67 type Error = Error;
68
69 fn try_from(identifier: &str) -> Result<Self> {
71 Self::from_str(identifier)
72 }
73}
74
75#[cfg(test)]
76pub(crate) mod tests {
77 use super::*;
78 use snarkvm_console_network::MainnetV0;
79
80 type CurrentNetwork = MainnetV0;
81
82 const ITERATIONS: usize = 100;
83
84 pub(crate) fn sample_identifier<N: Network>(rng: &mut TestRng) -> Result<Identifier<N>> {
86 let string = sample_identifier_as_string::<N>(rng)?;
88 let field = Field::<N>::from_bits_le(&string.as_bytes().to_bits_le())?;
90 Ok(Identifier(field, u8::try_from(string.len()).or_halt_with::<CurrentNetwork>("Invalid identifier length")))
92 }
93
94 pub(crate) fn sample_identifier_as_string<N: Network>(rng: &mut TestRng) -> Result<String> {
96 let string = "a".to_string()
98 + &rng
99 .sample_iter(&Alphanumeric)
100 .take(Field::<N>::size_in_data_bits() / (8 * 2))
101 .map(char::from)
102 .collect::<String>();
103 let max_bytes = Field::<N>::size_in_data_bits() / 8; match string.len() <= max_bytes {
106 true => Ok(string),
108 false => bail!("Identifier exceeds the maximum capacity allowed"),
109 }
110 }
111
112 pub(crate) fn sample_lowercase_identifier_as_string<N: Network>(rng: &mut TestRng) -> Result<String> {
114 let string = sample_identifier_as_string::<N>(rng)?;
116 Ok(string.to_lowercase())
118 }
119
120 #[test]
121 fn test_try_from() -> Result<()> {
122 let mut rng = TestRng::default();
123
124 for _ in 0..ITERATIONS {
125 let expected_string = sample_identifier_as_string::<CurrentNetwork>(&mut rng)?;
127 let expected_field = Field::<CurrentNetwork>::from_bits_le(&expected_string.as_bytes().to_bits_le())?;
129
130 let candidate = Identifier::<CurrentNetwork>::try_from(expected_string.as_str())?;
132 assert_eq!(expected_field, candidate.0);
133 assert_eq!(expected_string.len(), candidate.1 as usize);
134 }
135 Ok(())
136 }
137
138 #[test]
139 fn test_identifier_try_from_illegal() {
140 assert!(Identifier::<CurrentNetwork>::try_from("123").is_err());
141 assert!(Identifier::<CurrentNetwork>::try_from("abc\x08def").is_err());
142 assert!(Identifier::<CurrentNetwork>::try_from("abc\u{202a}def").is_err());
143 }
144}