indy_data_types/anoncreds/
nonce.rs1use std::convert::TryFrom;
2use std::fmt;
3use std::hash::{Hash, Hasher};
4
5#[cfg(feature = "serde")]
6use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer};
7
8#[cfg(any(feature = "cl", feature = "cl_native"))]
9use crate::anoncreds_clsignatures::{new_nonce, Nonce as ClNonce};
10use crate::ConversionError;
11
12pub struct Nonce {
13 strval: String,
14 #[cfg(any(feature = "cl", feature = "cl_native"))]
15 native: ClNonce,
16}
17
18impl Nonce {
19 #[cfg(any(feature = "cl", feature = "cl_native"))]
20 #[inline]
21 pub fn new() -> Result<Self, ConversionError> {
22 let native = new_nonce()
23 .map_err(|err| ConversionError::from_msg(format!("Error creating nonce: {}", err)))?;
24 Self::from_native(native)
25 }
26
27 #[cfg(any(feature = "cl", feature = "cl_native"))]
28 #[inline]
29 pub fn from_native(native: ClNonce) -> Result<Self, ConversionError> {
30 let strval = native.to_dec().map_err(|e| e.to_string())?;
31 Ok(Self { strval, native })
32 }
33
34 #[cfg(any(feature = "cl", feature = "cl_native"))]
35 #[inline]
36 pub fn as_native(&self) -> &ClNonce {
37 &self.native
38 }
39
40 #[cfg(any(feature = "cl", feature = "cl_native"))]
41 #[inline]
42 pub fn into_native(self) -> ClNonce {
43 self.native
44 }
45
46 pub fn from_dec<S: Into<String>>(value: S) -> Result<Self, ConversionError> {
47 let strval = value.into();
48 if strval.is_empty() {
49 return Err("Invalid bignum: empty value".into());
50 }
51 for c in strval.chars() {
52 if !c.is_ascii_digit() {
53 return Err("Invalid bignum value".into());
54 }
55 }
56 #[cfg(any(feature = "cl", feature = "cl_native"))]
57 {
58 let native = ClNonce::from_dec(&strval).map_err(|e| e.to_string())?;
59 Ok(Self { strval, native })
60 }
61 #[cfg(not(any(feature = "cl", feature = "cl_native")))]
62 Ok(Self { strval })
63 }
64
65 pub fn try_clone(&self) -> Result<Self, ConversionError> {
66 Self::from_dec(self.strval.clone())
67 }
68}
69
70impl Hash for Nonce {
71 fn hash<H: Hasher>(&self, state: &mut H) {
72 self.strval.hash(state);
73 }
74}
75
76impl PartialEq for Nonce {
77 fn eq(&self, other: &Nonce) -> bool {
78 self.strval == other.strval
79 }
80}
81
82impl Eq for Nonce {}
83
84impl TryFrom<i64> for Nonce {
85 type Error = ConversionError;
86
87 fn try_from(value: i64) -> Result<Self, Self::Error> {
88 Self::from_dec(value.to_string())
89 }
90}
91
92impl TryFrom<u64> for Nonce {
93 type Error = ConversionError;
94
95 fn try_from(value: u64) -> Result<Self, Self::Error> {
96 Self::from_dec(value.to_string())
97 }
98}
99
100impl TryFrom<u128> for Nonce {
101 type Error = ConversionError;
102
103 fn try_from(value: u128) -> Result<Self, Self::Error> {
104 Self::from_dec(value.to_string())
105 }
106}
107
108impl TryFrom<&str> for Nonce {
109 type Error = ConversionError;
110
111 fn try_from(value: &str) -> Result<Self, Self::Error> {
112 Self::from_dec(value)
113 }
114}
115
116impl TryFrom<String> for Nonce {
117 type Error = ConversionError;
118
119 fn try_from(value: String) -> Result<Self, Self::Error> {
120 Self::from_dec(value)
121 }
122}
123
124impl AsRef<str> for Nonce {
125 fn as_ref(&self) -> &str {
126 &self.strval
127 }
128}
129
130impl fmt::Debug for Nonce {
131 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
132 f.debug_tuple("Nonce").field(&self.strval).finish()
133 }
134}
135
136impl fmt::Display for Nonce {
137 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138 self.strval.fmt(f)
139 }
140}
141
142impl std::ops::Deref for Nonce {
143 type Target = str;
144
145 fn deref(&self) -> &Self::Target {
146 &self.strval
147 }
148}
149
150#[cfg(feature = "serde")]
151impl Serialize for Nonce {
152 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
153 where
154 S: Serializer,
155 {
156 serializer.serialize_str(&self.strval)
157 }
158}
159
160#[cfg(feature = "serde")]
161impl<'a> Deserialize<'a> for Nonce {
162 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
163 where
164 D: Deserializer<'a>,
165 {
166 struct BigNumberVisitor;
167
168 impl<'a> Visitor<'a> for BigNumberVisitor {
169 type Value = Nonce;
170
171 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
172 formatter.write_str("integer or string nonce")
173 }
174
175 fn visit_i64<E>(self, value: i64) -> Result<Nonce, E>
176 where
177 E: serde::de::Error,
178 {
179 Nonce::try_from(value).map_err(E::custom)
180 }
181
182 fn visit_u64<E>(self, value: u64) -> Result<Nonce, E>
183 where
184 E: serde::de::Error,
185 {
186 Nonce::try_from(value).map_err(E::custom)
187 }
188
189 fn visit_u128<E>(self, value: u128) -> Result<Nonce, E>
190 where
191 E: serde::de::Error,
192 {
193 Nonce::try_from(value).map_err(E::custom)
194 }
195
196 fn visit_str<E>(self, value: &str) -> Result<Nonce, E>
197 where
198 E: serde::de::Error,
199 {
200 Nonce::from_dec(value).map_err(E::custom)
201 }
202 }
203
204 deserializer.deserialize_str(BigNumberVisitor)
205 }
206}
207
208#[cfg(test)]
209mod tests {
210 use super::*;
211
212 #[test]
213 fn nonce_validate() {
214 let valid = ["0", "1000000000000000000000000000000000"];
215 for v in valid.iter() {
216 assert!(Nonce::try_from(*v).is_ok())
217 }
218
219 let invalid = [
220 "-1000000000000000000000000000000000",
221 "-1",
222 "notanumber",
223 "",
224 "-",
225 "+1",
226 "1a",
227 ];
228 for v in invalid.iter() {
229 assert!(Nonce::try_from(*v).is_err())
230 }
231 }
232
233 #[cfg(feature = "serde")]
234 #[test]
235 fn nonce_serialize() {
236 let val = Nonce::try_from("10000").unwrap();
237 let ser = serde_json::to_string(&val).unwrap();
238 assert_eq!(ser, "\"10000\"");
239 let des = serde_json::from_str::<Nonce>(&ser).unwrap();
240 assert_eq!(val, des);
241 }
242
243 #[cfg(all(feature = "serde", any(feature = "cl", feature = "cl_native")))]
244 #[test]
245 fn nonce_convert() {
246 let nonce = ClNonce::new().expect("Error creating nonce");
247 let ser = serde_json::to_string(&nonce).unwrap();
248 let des = serde_json::from_str::<Nonce>(&ser).unwrap();
249 let ser2 = serde_json::to_string(&des).unwrap();
250 let nonce_des = serde_json::from_str::<ClNonce>(&ser2).unwrap();
251 assert_eq!(nonce, nonce_des);
252
253 let nonce = Nonce::new().unwrap();
254 let strval = nonce.to_string();
255 let unonce = nonce.into_native();
256 assert_eq!(strval, unonce.to_dec().unwrap());
257 }
258}