Skip to main content

dpp/document/accessors/
mod.rs

1pub(crate) mod v0;
2
3pub use v0::*;
4
5use crate::document::Document;
6use crate::identity::TimestampMillis;
7use crate::prelude::{BlockHeight, CoreBlockHeight, Revision};
8use platform_value::{Identifier, Value};
9use std::collections::BTreeMap;
10
11impl DocumentV0Getters for Document {
12    fn id(&self) -> Identifier {
13        match self {
14            Document::V0(v0) => v0.id,
15        }
16    }
17
18    fn id_ref(&self) -> &Identifier {
19        match self {
20            Document::V0(v0) => &v0.id,
21        }
22    }
23
24    fn owner_id(&self) -> Identifier {
25        match self {
26            Document::V0(v0) => v0.owner_id,
27        }
28    }
29
30    fn owner_id_ref(&self) -> &Identifier {
31        match self {
32            Document::V0(v0) => &v0.owner_id,
33        }
34    }
35
36    fn properties(&self) -> &BTreeMap<String, Value> {
37        match self {
38            Document::V0(v0) => &v0.properties,
39        }
40    }
41
42    fn properties_mut(&mut self) -> &mut BTreeMap<String, Value> {
43        match self {
44            Document::V0(v0) => &mut v0.properties,
45        }
46    }
47
48    fn properties_consumed(self) -> BTreeMap<String, Value> {
49        match self {
50            Document::V0(v0) => v0.properties,
51        }
52    }
53
54    fn revision(&self) -> Option<Revision> {
55        match self {
56            Document::V0(v0) => v0.revision,
57        }
58    }
59
60    fn created_at(&self) -> Option<TimestampMillis> {
61        match self {
62            Document::V0(v0) => v0.created_at,
63        }
64    }
65
66    fn updated_at(&self) -> Option<TimestampMillis> {
67        match self {
68            Document::V0(v0) => v0.updated_at,
69        }
70    }
71
72    fn transferred_at(&self) -> Option<TimestampMillis> {
73        match self {
74            Document::V0(v0) => v0.transferred_at,
75        }
76    }
77
78    fn created_at_block_height(&self) -> Option<BlockHeight> {
79        match self {
80            Document::V0(v0) => v0.created_at_block_height,
81        }
82    }
83
84    fn updated_at_block_height(&self) -> Option<BlockHeight> {
85        match self {
86            Document::V0(v0) => v0.updated_at_block_height,
87        }
88    }
89
90    fn transferred_at_block_height(&self) -> Option<BlockHeight> {
91        match self {
92            Document::V0(v0) => v0.transferred_at_block_height,
93        }
94    }
95
96    fn created_at_core_block_height(&self) -> Option<CoreBlockHeight> {
97        match self {
98            Document::V0(v0) => v0.created_at_core_block_height,
99        }
100    }
101
102    fn updated_at_core_block_height(&self) -> Option<CoreBlockHeight> {
103        match self {
104            Document::V0(v0) => v0.updated_at_core_block_height,
105        }
106    }
107
108    fn transferred_at_core_block_height(&self) -> Option<CoreBlockHeight> {
109        match self {
110            Document::V0(v0) => v0.transferred_at_core_block_height,
111        }
112    }
113
114    fn creator_id(&self) -> Option<Identifier> {
115        match self {
116            Document::V0(v0) => v0.creator_id,
117        }
118    }
119
120    fn contract_version(&self) -> Option<u32> {
121        match self {
122            Document::V0(v0) => v0.contract_version,
123        }
124    }
125}
126
127impl DocumentV0Setters for Document {
128    fn set_id(&mut self, id: Identifier) {
129        match self {
130            Document::V0(v0) => v0.id = id,
131        }
132    }
133
134    fn set_owner_id(&mut self, owner_id: Identifier) {
135        match self {
136            Document::V0(v0) => v0.owner_id = owner_id,
137        }
138    }
139
140    fn set_properties(&mut self, properties: BTreeMap<String, Value>) {
141        match self {
142            Document::V0(v0) => v0.properties = properties,
143        }
144    }
145
146    fn set_revision(&mut self, revision: Option<Revision>) {
147        match self {
148            Document::V0(v0) => v0.revision = revision,
149        }
150    }
151
152    fn bump_revision(&mut self) {
153        match self {
154            Document::V0(v0) => v0.bump_revision(),
155        }
156    }
157
158    fn set_created_at(&mut self, created_at: Option<TimestampMillis>) {
159        match self {
160            Document::V0(v0) => v0.created_at = created_at,
161        }
162    }
163
164    fn set_updated_at(&mut self, updated_at: Option<TimestampMillis>) {
165        match self {
166            Document::V0(v0) => v0.updated_at = updated_at,
167        }
168    }
169
170    fn set_transferred_at(&mut self, transferred_at: Option<TimestampMillis>) {
171        match self {
172            Document::V0(v0) => v0.transferred_at = transferred_at,
173        }
174    }
175
176    fn set_created_at_block_height(&mut self, created_at_block_height: Option<u64>) {
177        match self {
178            Document::V0(v0) => v0.created_at_block_height = created_at_block_height,
179        }
180    }
181
182    fn set_updated_at_block_height(&mut self, updated_at_block_height: Option<u64>) {
183        match self {
184            Document::V0(v0) => v0.updated_at_block_height = updated_at_block_height,
185        }
186    }
187
188    fn set_transferred_at_block_height(&mut self, transferred_at_block_height: Option<u64>) {
189        match self {
190            Document::V0(v0) => v0.transferred_at_block_height = transferred_at_block_height,
191        }
192    }
193
194    fn set_created_at_core_block_height(&mut self, created_at_core_block_height: Option<u32>) {
195        match self {
196            Document::V0(v0) => v0.created_at_core_block_height = created_at_core_block_height,
197        }
198    }
199
200    fn set_updated_at_core_block_height(&mut self, updated_at_core_block_height: Option<u32>) {
201        match self {
202            Document::V0(v0) => v0.updated_at_core_block_height = updated_at_core_block_height,
203        }
204    }
205
206    fn set_transferred_at_core_block_height(
207        &mut self,
208        transferred_at_core_block_height: Option<u32>,
209    ) {
210        match self {
211            Document::V0(v0) => {
212                v0.transferred_at_core_block_height = transferred_at_core_block_height
213            }
214        }
215    }
216
217    fn set_creator_id(&mut self, creator_id: Option<Identifier>) {
218        match self {
219            Document::V0(v0) => v0.creator_id = creator_id,
220        }
221    }
222
223    fn set_contract_version(&mut self, contract_version: Option<u32>) {
224        match self {
225            Document::V0(v0) => v0.contract_version = contract_version,
226        }
227    }
228}
229
230#[cfg(test)]
231mod tests {
232    use super::*;
233    use crate::document::v0::DocumentV0;
234    use crate::prelude::Revision;
235
236    fn make_doc() -> Document {
237        Document::V0(DocumentV0 {
238            contract_version: None,
239            id: Identifier::new([1u8; 32]),
240            owner_id: Identifier::new([2u8; 32]),
241            properties: BTreeMap::new(),
242            revision: Some(1),
243            created_at: Some(10),
244            updated_at: Some(20),
245            transferred_at: Some(30),
246            created_at_block_height: Some(100),
247            updated_at_block_height: Some(200),
248            transferred_at_block_height: Some(300),
249            created_at_core_block_height: Some(1),
250            updated_at_core_block_height: Some(2),
251            transferred_at_core_block_height: Some(3),
252            creator_id: Some(Identifier::new([9u8; 32])),
253        })
254    }
255
256    // ================================================================
257    //  Document-enum getters forward to the V0 variant.
258    // ================================================================
259
260    #[test]
261    fn getters_forward_all_fields_to_v0() {
262        let doc = make_doc();
263        assert_eq!(doc.id(), Identifier::new([1u8; 32]));
264        assert_eq!(doc.owner_id(), Identifier::new([2u8; 32]));
265        assert_eq!(doc.id_ref(), &Identifier::new([1u8; 32]));
266        assert_eq!(doc.owner_id_ref(), &Identifier::new([2u8; 32]));
267        assert_eq!(doc.revision(), Some(1));
268        assert_eq!(doc.created_at(), Some(10));
269        assert_eq!(doc.updated_at(), Some(20));
270        assert_eq!(doc.transferred_at(), Some(30));
271        assert_eq!(doc.created_at_block_height(), Some(100));
272        assert_eq!(doc.updated_at_block_height(), Some(200));
273        assert_eq!(doc.transferred_at_block_height(), Some(300));
274        assert_eq!(doc.created_at_core_block_height(), Some(1));
275        assert_eq!(doc.updated_at_core_block_height(), Some(2));
276        assert_eq!(doc.transferred_at_core_block_height(), Some(3));
277        assert_eq!(doc.creator_id(), Some(Identifier::new([9u8; 32])));
278        assert!(doc.properties().is_empty());
279    }
280
281    // ================================================================
282    //  Document-enum properties_consumed returns the inner BTreeMap.
283    // ================================================================
284
285    #[test]
286    fn properties_consumed_forwards_to_v0() {
287        let Document::V0(mut v0) = make_doc();
288        v0.properties.insert("k".into(), Value::U64(77));
289        let doc = Document::V0(v0);
290        let map = doc.properties_consumed();
291        assert_eq!(map.get("k"), Some(&Value::U64(77)));
292    }
293
294    // ================================================================
295    //  Document-enum properties_mut allows mutation.
296    // ================================================================
297
298    #[test]
299    fn properties_mut_allows_mutation_via_enum() {
300        let mut doc = make_doc();
301        doc.properties_mut().insert("x".into(), Value::U64(5));
302        assert_eq!(doc.properties().get("x"), Some(&Value::U64(5)));
303    }
304
305    // ================================================================
306    //  Document-enum setters forward to the V0 variant.
307    // ================================================================
308
309    #[test]
310    fn setters_forward_all_fields_to_v0() {
311        let mut doc = make_doc();
312        doc.set_id(Identifier::new([42u8; 32]));
313        doc.set_owner_id(Identifier::new([43u8; 32]));
314        let mut p = BTreeMap::new();
315        p.insert("z".into(), Value::Bool(true));
316        doc.set_properties(p.clone());
317        doc.set_revision(Some(99));
318        doc.set_created_at(Some(1_000_000));
319        doc.set_updated_at(Some(2_000_000));
320        doc.set_transferred_at(Some(3_000_000));
321        doc.set_created_at_block_height(Some(111));
322        doc.set_updated_at_block_height(Some(222));
323        doc.set_transferred_at_block_height(Some(333));
324        doc.set_created_at_core_block_height(Some(4));
325        doc.set_updated_at_core_block_height(Some(5));
326        doc.set_transferred_at_core_block_height(Some(6));
327        doc.set_creator_id(Some(Identifier::new([7u8; 32])));
328
329        assert_eq!(doc.id(), Identifier::new([42u8; 32]));
330        assert_eq!(doc.owner_id(), Identifier::new([43u8; 32]));
331        assert_eq!(doc.properties(), &p);
332        assert_eq!(doc.revision(), Some(99));
333        assert_eq!(doc.created_at(), Some(1_000_000));
334        assert_eq!(doc.updated_at(), Some(2_000_000));
335        assert_eq!(doc.transferred_at(), Some(3_000_000));
336        assert_eq!(doc.created_at_block_height(), Some(111));
337        assert_eq!(doc.updated_at_block_height(), Some(222));
338        assert_eq!(doc.transferred_at_block_height(), Some(333));
339        assert_eq!(doc.created_at_core_block_height(), Some(4));
340        assert_eq!(doc.updated_at_core_block_height(), Some(5));
341        assert_eq!(doc.transferred_at_core_block_height(), Some(6));
342        assert_eq!(doc.creator_id(), Some(Identifier::new([7u8; 32])));
343    }
344
345    // ================================================================
346    //  Document-enum bump_revision forwards to the V0 saturating_add.
347    //  Unlike increment_revision, bump_revision never errors and
348    //  saturates at Revision::MAX.
349    // ================================================================
350
351    #[test]
352    fn bump_revision_via_enum_saturates_at_max() {
353        let mut doc = make_doc();
354        doc.set_revision(Some(Revision::MAX));
355        doc.bump_revision();
356        assert_eq!(doc.revision(), Some(Revision::MAX));
357    }
358
359    #[test]
360    fn bump_revision_via_enum_is_noop_for_none() {
361        let mut doc = make_doc();
362        doc.set_revision(None);
363        doc.bump_revision();
364        assert_eq!(doc.revision(), None);
365    }
366
367    // ================================================================
368    //  Document::get (default impl on the trait) returns a property
369    //  at the given path or None.
370    // ================================================================
371
372    #[test]
373    fn get_returns_property_by_path() {
374        let mut doc = make_doc();
375        doc.properties_mut().insert("a".into(), Value::U64(1));
376        assert_eq!(doc.get("a"), Some(&Value::U64(1)));
377        assert_eq!(doc.get("missing"), None);
378    }
379}