Skip to main content

dpp/tokens/contract_info/
mod.rs

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