Skip to main content

dpp/tokens/contract_info/
mod.rs

1use crate::data_contract::TokenContractPosition;
2use crate::tokens::contract_info::v0::TokenContractInfoV0;
3use crate::ProtocolError;
4use bincode::Encode;
5use derive_more::From;
6use platform_serialization::de::Decode;
7use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
8use platform_value::Identifier;
9use platform_version::version::PlatformVersion;
10use platform_versioning::PlatformVersioned;
11
12mod methods;
13pub mod v0;
14
15#[derive(
16    Debug,
17    Clone,
18    Encode,
19    Decode,
20    PlatformDeserialize,
21    PlatformSerialize,
22    PlatformVersioned,
23    From,
24    PartialEq,
25)]
26#[platform_serialize(unversioned)] //versioned directly, no need to use platform_version
27#[cfg_attr(
28    any(feature = "fixtures-and-mocks", feature = "serde-conversion"),
29    derive(serde::Serialize, serde::Deserialize),
30    serde(tag = "$formatVersion")
31)]
32pub enum TokenContractInfo {
33    #[cfg_attr(
34        any(feature = "fixtures-and-mocks", feature = "serde-conversion"),
35        serde(rename = "0")
36    )]
37    V0(TokenContractInfoV0),
38}
39
40#[cfg(all(feature = "json-conversion", feature = "serde-conversion"))]
41impl crate::serialization::JsonConvertible for TokenContractInfo {}
42
43#[cfg(all(feature = "value-conversion", feature = "serde-conversion"))]
44impl crate::serialization::ValueConvertible for TokenContractInfo {}
45
46impl TokenContractInfo {
47    pub fn new(
48        contract_id: Identifier,
49        token_contract_position: TokenContractPosition,
50        platform_version: &PlatformVersion,
51    ) -> Result<Self, ProtocolError> {
52        match platform_version
53            .dpp
54            .token_versions
55            .token_contract_info_default_structure_version
56        {
57            0 => Ok(TokenContractInfo::V0(TokenContractInfoV0 {
58                contract_id,
59                token_contract_position,
60            })),
61            version => Err(ProtocolError::UnknownVersionMismatch {
62                method: "TokenContractInfo::new".to_string(),
63                known_versions: vec![0],
64                received: version,
65            }),
66        }
67    }
68}
69
70#[cfg(all(
71    test,
72    feature = "json-conversion",
73    feature = "value-conversion",
74    feature = "serde-conversion"
75))]
76mod json_convertible_tests {
77    use super::*;
78    use platform_value::{platform_value, Identifier};
79    use serde_json::json;
80
81    fn fixture() -> TokenContractInfo {
82        TokenContractInfo::V0(crate::tokens::contract_info::v0::TokenContractInfoV0 {
83            contract_id: Identifier::new([0xab; 32]),
84            token_contract_position: 7,
85        })
86    }
87
88    // `TokenContractInfo` uses the standard `tag = "$formatVersion"` convention.
89
90    #[test]
91    fn json_round_trip_with_full_wire_shape() {
92        use crate::serialization::JsonConvertible;
93        let original = fixture();
94        let json = original.to_json().expect("to_json");
95        // `Identifier` renders as base58 in JSON HR. `tokenContractPosition` is
96        // a `u16` (TokenContractPosition alias); JSON has only one number type
97        // so the U16 distinction is erased — the Value-path assertion below
98        // uses `7u16` to lock in the sized variant.
99        assert_eq!(
100            json,
101            json!({
102                "$formatVersion": "0",
103                "contractId": "CZ8YUVdk7znjrUmnb5n7kgySk9yRAsQDYmyCxzfSky9t",
104                "tokenContractPosition": 7,
105            })
106        );
107        let recovered = TokenContractInfo::from_json(json).expect("from_json");
108        assert_eq!(original, recovered);
109    }
110
111    #[test]
112    fn value_round_trip_with_full_wire_shape() {
113        use crate::serialization::ValueConvertible;
114        let original = fixture();
115        let value = original.to_object().expect("to_object");
116        let contract_id = Identifier::new([0xab; 32]);
117        assert_eq!(
118            value,
119            platform_value!({
120                "$formatVersion": "0",
121                "contractId": contract_id,
122                "tokenContractPosition": 7u16,
123            })
124        );
125        let recovered = TokenContractInfo::from_object(value).expect("from_object");
126        assert_eq!(original, recovered);
127    }
128}