cardano_serialization_lib/serialization/certificates/
stake_registration.rs

1use crate::serialization::map_names::CertificateIndexNames;
2use crate::serialization::utils::{check_index, check_len, serialize_and_check_index};
3use crate::*;
4use cbor_event::Len;
5use num_traits::{FromPrimitive, ToPrimitive};
6
7impl cbor_event::se::Serialize for StakeRegistration {
8    fn serialize<'se, W: Write>(
9        &self,
10        serializer: &'se mut Serializer<W>,
11    ) -> cbor_event::Result<&'se mut Serializer<W>> {
12        if self.coin.is_some() {
13            serialize_as_conway(self, serializer)
14        } else {
15            serialize_as_legacy(self, serializer)
16        }
17    }
18}
19
20fn serialize_as_legacy<'se, W: Write>(
21    cert: &StakeRegistration,
22    serializer: &'se mut Serializer<W>,
23) -> cbor_event::Result<&'se mut Serializer<W>> {
24    serializer.write_array(cbor_event::Len::Len(2))?;
25
26    let proposal_index = CertificateIndexNames::StakeRegistrationLegacy.to_u64();
27    serialize_and_check_index(serializer, proposal_index, "StakeRegistrationLegacy")?;
28
29    cert.stake_credential.serialize(serializer)?;
30    Ok(serializer)
31}
32
33fn serialize_as_conway<'se, W: Write>(
34    cert: &StakeRegistration,
35    serializer: &'se mut Serializer<W>,
36) -> cbor_event::Result<&'se mut Serializer<W>> {
37    serializer.write_array(cbor_event::Len::Len(3))?;
38
39    let proposal_index = CertificateIndexNames::StakeRegistrationConway.to_u64();
40    serialize_and_check_index(serializer, proposal_index, "StakeRegistrationConway")?;
41
42    cert.stake_credential.serialize(serializer)?;
43    if let Some(coin) = cert.coin {
44        coin.serialize(serializer)?;
45    }
46    Ok(serializer)
47}
48
49impl_deserialize_for_wrapped_tuple!(StakeRegistration);
50
51impl DeserializeEmbeddedGroup for StakeRegistration {
52    fn deserialize_as_embedded_group<R: BufRead + Seek>(
53        raw: &mut Deserializer<R>,
54        len: Len,
55    ) -> Result<Self, DeserializeError> {
56        let cert_index = raw.unsigned_integer()?;
57        let index_enum = CertificateIndexNames::from_u64(cert_index);
58        match index_enum {
59            Some(CertificateIndexNames::StakeRegistrationLegacy) => {
60                deserialize_legacy(raw, cert_index, len)
61            }
62            Some(CertificateIndexNames::StakeRegistrationConway) => {
63                deserialize_conway(raw, cert_index, len)
64            }
65            _ => Err(DeserializeFailure::FixedValuesMismatch {
66                found: Key::Uint(cert_index),
67                expected: vec![
68                    Key::OptUint(CertificateIndexNames::StakeRegistrationLegacy.to_u64()),
69                    Key::OptUint(CertificateIndexNames::StakeRegistrationConway.to_u64()),
70                ],
71            })
72            .map_err(|e| DeserializeError::from(e).annotate("cert_index")),
73        }
74    }
75}
76
77fn deserialize_legacy<R: BufRead + Seek>(
78    raw: &mut Deserializer<R>,
79    cert_index: u64,
80    len: Len,
81) -> Result<StakeRegistration, DeserializeError> {
82    (|| -> Result<_, DeserializeError> {
83        check_len(len, 2, "(cert_index, stake_credential)")?;
84        let desired_index = CertificateIndexNames::StakeRegistrationLegacy.to_u64();
85        check_index(cert_index, desired_index, "cert_index")?;
86
87        let stake_credential =
88            Credential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?;
89
90        return Ok(StakeRegistration {
91            stake_credential,
92            coin: None,
93        });
94    })()
95    .map_err(|e| e.annotate("StakeRegistration (legacy)"))
96}
97
98fn deserialize_conway<R: BufRead + Seek>(
99    raw: &mut Deserializer<R>,
100    cert_index: u64,
101    len: Len,
102) -> Result<StakeRegistration, DeserializeError> {
103    (|| -> Result<_, DeserializeError> {
104        check_len(len, 3, "(cert_index, stake_credential, coin)")?;
105        let desired_index = CertificateIndexNames::StakeRegistrationConway.to_u64();
106        check_index(cert_index, desired_index, "cert_index")?;
107
108        let stake_credential =
109            Credential::deserialize(raw).map_err(|e| e.annotate("stake_credential"))?;
110
111        let coin = Coin::deserialize(raw).map_err(|e| e.annotate("coin"))?;
112
113        return Ok(StakeRegistration {
114            stake_credential,
115            coin: Some(coin),
116        });
117    })()
118    .map_err(|e| e.annotate("StakeRegistration (conway)"))
119}