1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
mod bytes;
mod equal;
mod from_bits;
mod from_field;
mod parse;
mod serialize;
mod size_in_bits;
mod to_bits;
mod to_field;
use snarkvm_console_network::Network;
use snarkvm_console_types::{prelude::*, Field};
#[derive(Copy, Clone)]
pub struct Identifier<N: Network>(Field<N>, u8); impl<N: Network> From<&Identifier<N>> for Identifier<N> {
fn from(identifier: &Identifier<N>) -> Self {
*identifier
}
}
impl<N: Network> TryFrom<String> for Identifier<N> {
type Error = Error;
fn try_from(identifier: String) -> Result<Self> {
Self::from_str(&identifier)
}
}
impl<N: Network> TryFrom<&String> for Identifier<N> {
type Error = Error;
fn try_from(identifier: &String) -> Result<Self> {
Self::from_str(identifier)
}
}
impl<N: Network> TryFrom<&str> for Identifier<N> {
type Error = Error;
fn try_from(identifier: &str) -> Result<Self> {
Self::from_str(identifier)
}
}
#[cfg(test)]
pub(crate) mod tests {
use super::*;
use snarkvm_console_network::Testnet3;
type CurrentNetwork = Testnet3;
const ITERATIONS: usize = 100;
pub(crate) fn sample_identifier<N: Network>(rng: &mut TestRng) -> Result<Identifier<N>> {
let string = sample_identifier_as_string::<N>(rng)?;
let field = Field::<N>::from_bits_le(&string.as_bytes().to_bits_le())?;
Ok(Identifier(field, u8::try_from(string.len()).or_halt_with::<CurrentNetwork>("Invalid identifier length")))
}
pub(crate) fn sample_identifier_as_string<N: Network>(rng: &mut TestRng) -> Result<String> {
let string = "a".to_string()
+ &rng
.sample_iter(&Alphanumeric)
.take(Field::<N>::size_in_data_bits() / (8 * 2))
.map(char::from)
.collect::<String>();
let max_bytes = Field::<N>::size_in_data_bits() / 8; match string.len() <= max_bytes {
true => Ok(string),
false => bail!("Identifier exceeds the maximum capacity allowed"),
}
}
#[test]
fn test_try_from() -> Result<()> {
let mut rng = TestRng::default();
for _ in 0..ITERATIONS {
let expected_string = sample_identifier_as_string::<CurrentNetwork>(&mut rng)?;
let expected_field = Field::<CurrentNetwork>::from_bits_le(&expected_string.as_bytes().to_bits_le())?;
let candidate = Identifier::<CurrentNetwork>::try_from(expected_string.as_str())?;
assert_eq!(expected_field, candidate.0);
assert_eq!(expected_string.len(), candidate.1 as usize);
}
Ok(())
}
#[test]
fn test_identifier_try_from_illegal() {
assert!(Identifier::<CurrentNetwork>::try_from("123").is_err());
assert!(Identifier::<CurrentNetwork>::try_from("abc\x08def").is_err());
assert!(Identifier::<CurrentNetwork>::try_from("abc\u{202a}def").is_err());
}
}