cardano_serialization_lib/serialization/crypto/
nonce.rs

1use std::convert::TryInto;
2use crate::protocol_types::{CBORSpecial, Deserialize};
3use crate::{DeserializeError, DeserializeFailure, Nonce};
4use cbor_event::de::Deserializer;
5use cbor_event::se::Serializer;
6
7impl cbor_event::se::Serialize for Nonce {
8    fn serialize<'se, W: std::io::Write>(
9        &self,
10        serializer: &'se mut Serializer<W>,
11    ) -> cbor_event::Result<&'se mut Serializer<W>> {
12        match &self.hash {
13            Some(hash) => {
14                serializer.write_array(cbor_event::Len::Len(2))?;
15                serializer.write_unsigned_integer(1)?;
16                serializer.write_bytes(hash)
17            }
18            None => {
19                serializer.write_array(cbor_event::Len::Len(1))?;
20                serializer.write_unsigned_integer(0)
21            }
22        }
23    }
24}
25
26impl Deserialize for Nonce {
27    fn deserialize<R: std::io::BufRead>(
28        raw: &mut Deserializer<R>,
29    ) -> Result<Self, DeserializeError> {
30        (|| -> Result<Self, DeserializeError> {
31            let len = raw.array()?;
32            let hash = match raw.unsigned_integer()? {
33                0 => None,
34                1 => {
35                    let bytes = raw.bytes()?;
36                    if bytes.len() != Self::HASH_LEN {
37                        return Err(DeserializeFailure::CBOR(cbor_event::Error::WrongLen(
38                            Self::HASH_LEN as u64,
39                            cbor_event::Len::Len(bytes.len() as u64),
40                            "hash length",
41                        ))
42                        .into());
43                    }
44                    Some(bytes[..Self::HASH_LEN].try_into().unwrap())
45                }
46                _ => return Err(DeserializeFailure::NoVariantMatched.into()),
47            };
48            match len {
49                cbor_event::Len::Len(n) => {
50                    let correct_len = match n {
51                        1 => hash.is_none(),
52                        2 => hash.is_some(),
53                        _ => false,
54                    };
55                    if !correct_len {
56                        return Err(DeserializeFailure::NoVariantMatched.into());
57                    }
58                }
59                cbor_event::Len::Indefinite => match raw.special()? {
60                    CBORSpecial::Break =>
61                    /* it's ok */
62                    {
63                        ()
64                    }
65                    _ => return Err(DeserializeFailure::EndingBreakMissing.into()),
66                },
67            };
68            Ok(Self { hash })
69        })()
70        .map_err(|e| e.annotate(stringify!($name)))
71    }
72}