indy_data_types/anoncreds/
nonce.rs

1use 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}