dpp/document/v0/
platform_value_conversion.rs1use crate::document::serialization_traits::DocumentPlatformValueMethodsV0;
2use crate::document::DocumentV0;
3use crate::version::PlatformVersion;
4use crate::ProtocolError;
5use platform_value::Value;
6use std::collections::BTreeMap;
7
8impl DocumentPlatformValueMethodsV0<'_> for DocumentV0 {
9 fn to_map_value(&self) -> Result<BTreeMap<String, Value>, ProtocolError> {
10 Ok(platform_value::to_value(self)?.into_btree_string_map()?)
11 }
12
13 fn into_map_value(self) -> Result<BTreeMap<String, Value>, ProtocolError> {
14 Ok(platform_value::to_value(self)?.into_btree_string_map()?)
15 }
16
17 fn into_value(self) -> Result<Value, ProtocolError> {
18 Ok(platform_value::to_value(self)?)
19 }
20
21 fn to_object(&self) -> Result<Value, ProtocolError> {
22 Ok(platform_value::to_value(self)?)
23 }
24
25 fn from_platform_value(
26 document_value: Value,
27 _platform_version: &PlatformVersion,
28 ) -> Result<Self, ProtocolError> {
29 Ok(platform_value::from_value(document_value)?)
30 }
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36 use crate::document::property_names;
37 use platform_value::Identifier;
38 use platform_version::version::PlatformVersion;
39
40 fn minimal_doc() -> DocumentV0 {
41 DocumentV0 {
42 id: Identifier::new([1u8; 32]),
43 owner_id: Identifier::new([2u8; 32]),
44 properties: BTreeMap::new(),
45 revision: None,
46 created_at: None,
47 updated_at: None,
48 transferred_at: None,
49 created_at_block_height: None,
50 updated_at_block_height: None,
51 transferred_at_block_height: None,
52 created_at_core_block_height: None,
53 updated_at_core_block_height: None,
54 transferred_at_core_block_height: None,
55 creator_id: None,
56 }
57 }
58
59 fn full_doc() -> DocumentV0 {
60 let mut props = BTreeMap::new();
61 props.insert("name".into(), Value::Text("Eve".into()));
62 props.insert("score".into(), Value::U64(42));
63 DocumentV0 {
64 id: Identifier::new([7u8; 32]),
65 owner_id: Identifier::new([8u8; 32]),
66 properties: props,
67 revision: Some(3),
68 created_at: Some(1_700_000_000_000),
69 updated_at: Some(1_700_000_100_000),
70 transferred_at: Some(1_700_000_200_000),
71 created_at_block_height: Some(10),
72 updated_at_block_height: Some(20),
73 transferred_at_block_height: Some(30),
74 created_at_core_block_height: Some(1),
75 updated_at_core_block_height: Some(2),
76 transferred_at_core_block_height: Some(3),
77 creator_id: Some(Identifier::new([9u8; 32])),
78 }
79 }
80
81 #[test]
87 fn to_map_value_contains_id_and_owner_id_keys() {
88 let doc = minimal_doc();
89 let map = doc.to_map_value().expect("to_map_value should succeed");
90 assert!(map.contains_key(property_names::ID));
91 assert!(map.contains_key(property_names::OWNER_ID));
92 }
93
94 #[test]
95 fn to_map_value_contains_all_set_optional_fields() {
96 let doc = full_doc();
97 let map = doc.to_map_value().expect("to_map_value should succeed");
98 assert!(map.contains_key(property_names::REVISION));
99 assert!(map.contains_key(property_names::CREATED_AT));
100 assert!(map.contains_key(property_names::UPDATED_AT));
101 assert!(map.contains_key(property_names::TRANSFERRED_AT));
102 assert!(map.contains_key(property_names::CREATED_AT_BLOCK_HEIGHT));
103 assert!(map.contains_key(property_names::UPDATED_AT_BLOCK_HEIGHT));
104 assert!(map.contains_key(property_names::TRANSFERRED_AT_BLOCK_HEIGHT));
105 assert!(map.contains_key(property_names::CREATED_AT_CORE_BLOCK_HEIGHT));
106 assert!(map.contains_key(property_names::UPDATED_AT_CORE_BLOCK_HEIGHT));
107 assert!(map.contains_key(property_names::TRANSFERRED_AT_CORE_BLOCK_HEIGHT));
108 assert!(map.contains_key(property_names::CREATOR_ID));
109 assert!(map.contains_key("name"));
111 assert!(map.contains_key("score"));
112 }
113
114 #[test]
119 fn into_map_value_consumes_and_returns_same_shape_as_to_map_value() {
120 let doc = full_doc();
121 let from_ref = doc.to_map_value().expect("to_map_value");
122 let from_owned = doc.into_map_value().expect("into_map_value");
123 assert_eq!(from_ref, from_owned);
124 }
125
126 #[test]
131 fn to_object_returns_a_map_value() {
132 let doc = full_doc();
133 let v = doc.to_object().expect("to_object");
134 assert!(v.is_map(), "Expected a Value::Map, got {:?}", v);
135 }
136
137 #[test]
138 fn into_value_consumes_and_returns_a_map_value() {
139 let doc = full_doc();
140 let v = doc.into_value().expect("into_value");
141 assert!(v.is_map(), "Expected a Value::Map, got {:?}", v);
142 }
143
144 #[test]
149 fn from_platform_value_round_trip_preserves_all_fields() {
150 let platform_version = PlatformVersion::latest();
151 let doc = full_doc();
152 let v = doc.to_object().expect("to_object");
153 let recovered = DocumentV0::from_platform_value(v, platform_version)
154 .expect("from_platform_value should succeed");
155 assert_eq!(doc, recovered);
156 }
157
158 #[test]
159 fn from_platform_value_round_trip_with_minimal_fields() {
160 let platform_version = PlatformVersion::latest();
161 let doc = minimal_doc();
162 let v = doc.to_object().expect("to_object");
163 let recovered = DocumentV0::from_platform_value(v, platform_version)
164 .expect("from_platform_value should succeed");
165 assert_eq!(doc, recovered);
166 }
167
168 #[test]
173 fn from_platform_value_with_non_map_value_returns_error() {
174 let platform_version = PlatformVersion::latest();
175 let bad = Value::Text("not a document".to_string());
176 let result = DocumentV0::from_platform_value(bad, platform_version);
177 assert!(
178 result.is_err(),
179 "from_platform_value with a non-map Value should fail"
180 );
181 }
182}