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