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    fn moderated_at(&self) -> Option<TimestampMillis> {
127        match self {
128            Document::V0(v0) => v0.moderated_at,
129        }
130    }
131
132    fn moderated_by(&self) -> Option<Identifier> {
133        match self {
134            Document::V0(v0) => v0.moderated_by,
135        }
136    }
137}
138
139impl DocumentV0Setters for Document {
140    fn set_id(&mut self, id: Identifier) {
141        match self {
142            Document::V0(v0) => v0.id = id,
143        }
144    }
145
146    fn set_owner_id(&mut self, owner_id: Identifier) {
147        match self {
148            Document::V0(v0) => v0.owner_id = owner_id,
149        }
150    }
151
152    fn set_properties(&mut self, properties: BTreeMap<String, Value>) {
153        match self {
154            Document::V0(v0) => v0.properties = properties,
155        }
156    }
157
158    fn set_revision(&mut self, revision: Option<Revision>) {
159        match self {
160            Document::V0(v0) => v0.revision = revision,
161        }
162    }
163
164    fn bump_revision(&mut self) {
165        match self {
166            Document::V0(v0) => v0.bump_revision(),
167        }
168    }
169
170    fn set_created_at(&mut self, created_at: Option<TimestampMillis>) {
171        match self {
172            Document::V0(v0) => v0.created_at = created_at,
173        }
174    }
175
176    fn set_updated_at(&mut self, updated_at: Option<TimestampMillis>) {
177        match self {
178            Document::V0(v0) => v0.updated_at = updated_at,
179        }
180    }
181
182    fn set_transferred_at(&mut self, transferred_at: Option<TimestampMillis>) {
183        match self {
184            Document::V0(v0) => v0.transferred_at = transferred_at,
185        }
186    }
187
188    fn set_created_at_block_height(&mut self, created_at_block_height: Option<u64>) {
189        match self {
190            Document::V0(v0) => v0.created_at_block_height = created_at_block_height,
191        }
192    }
193
194    fn set_updated_at_block_height(&mut self, updated_at_block_height: Option<u64>) {
195        match self {
196            Document::V0(v0) => v0.updated_at_block_height = updated_at_block_height,
197        }
198    }
199
200    fn set_transferred_at_block_height(&mut self, transferred_at_block_height: Option<u64>) {
201        match self {
202            Document::V0(v0) => v0.transferred_at_block_height = transferred_at_block_height,
203        }
204    }
205
206    fn set_created_at_core_block_height(&mut self, created_at_core_block_height: Option<u32>) {
207        match self {
208            Document::V0(v0) => v0.created_at_core_block_height = created_at_core_block_height,
209        }
210    }
211
212    fn set_updated_at_core_block_height(&mut self, updated_at_core_block_height: Option<u32>) {
213        match self {
214            Document::V0(v0) => v0.updated_at_core_block_height = updated_at_core_block_height,
215        }
216    }
217
218    fn set_transferred_at_core_block_height(
219        &mut self,
220        transferred_at_core_block_height: Option<u32>,
221    ) {
222        match self {
223            Document::V0(v0) => {
224                v0.transferred_at_core_block_height = transferred_at_core_block_height
225            }
226        }
227    }
228
229    fn set_creator_id(&mut self, creator_id: Option<Identifier>) {
230        match self {
231            Document::V0(v0) => v0.creator_id = creator_id,
232        }
233    }
234
235    fn set_contract_version(&mut self, contract_version: Option<u32>) {
236        match self {
237            Document::V0(v0) => v0.contract_version = contract_version,
238        }
239    }
240
241    fn set_moderated_at(&mut self, moderated_at: Option<TimestampMillis>) {
242        match self {
243            Document::V0(v0) => v0.moderated_at = moderated_at,
244        }
245    }
246
247    fn set_moderated_by(&mut self, moderated_by: Option<Identifier>) {
248        match self {
249            Document::V0(v0) => v0.moderated_by = moderated_by,
250        }
251    }
252}
253
254#[cfg(test)]
255mod tests {
256    use super::*;
257    use crate::document::v0::DocumentV0;
258    use crate::prelude::Revision;
259
260    fn make_doc() -> Document {
261        Document::V0(DocumentV0 {
262            contract_version: None,
263            id: Identifier::new([1u8; 32]),
264            owner_id: Identifier::new([2u8; 32]),
265            properties: BTreeMap::new(),
266            revision: Some(1),
267            created_at: Some(10),
268            updated_at: Some(20),
269            transferred_at: Some(30),
270            created_at_block_height: Some(100),
271            updated_at_block_height: Some(200),
272            transferred_at_block_height: Some(300),
273            created_at_core_block_height: Some(1),
274            updated_at_core_block_height: Some(2),
275            transferred_at_core_block_height: Some(3),
276            creator_id: Some(Identifier::new([9u8; 32])),
277            moderated_at: None,
278            moderated_by: None,
279        })
280    }
281
282    // ================================================================
283    //  Document-enum getters forward to the V0 variant.
284    // ================================================================
285
286    #[test]
287    fn getters_forward_all_fields_to_v0() {
288        let doc = make_doc();
289        assert_eq!(doc.id(), Identifier::new([1u8; 32]));
290        assert_eq!(doc.owner_id(), Identifier::new([2u8; 32]));
291        assert_eq!(doc.id_ref(), &Identifier::new([1u8; 32]));
292        assert_eq!(doc.owner_id_ref(), &Identifier::new([2u8; 32]));
293        assert_eq!(doc.revision(), Some(1));
294        assert_eq!(doc.created_at(), Some(10));
295        assert_eq!(doc.updated_at(), Some(20));
296        assert_eq!(doc.transferred_at(), Some(30));
297        assert_eq!(doc.created_at_block_height(), Some(100));
298        assert_eq!(doc.updated_at_block_height(), Some(200));
299        assert_eq!(doc.transferred_at_block_height(), Some(300));
300        assert_eq!(doc.created_at_core_block_height(), Some(1));
301        assert_eq!(doc.updated_at_core_block_height(), Some(2));
302        assert_eq!(doc.transferred_at_core_block_height(), Some(3));
303        assert_eq!(doc.creator_id(), Some(Identifier::new([9u8; 32])));
304        assert!(doc.properties().is_empty());
305    }
306
307    // ================================================================
308    //  Document-enum properties_consumed returns the inner BTreeMap.
309    // ================================================================
310
311    #[test]
312    fn properties_consumed_forwards_to_v0() {
313        let Document::V0(mut v0) = make_doc();
314        v0.properties.insert("k".into(), Value::U64(77));
315        let doc = Document::V0(v0);
316        let map = doc.properties_consumed();
317        assert_eq!(map.get("k"), Some(&Value::U64(77)));
318    }
319
320    // ================================================================
321    //  Document-enum properties_mut allows mutation.
322    // ================================================================
323
324    #[test]
325    fn properties_mut_allows_mutation_via_enum() {
326        let mut doc = make_doc();
327        doc.properties_mut().insert("x".into(), Value::U64(5));
328        assert_eq!(doc.properties().get("x"), Some(&Value::U64(5)));
329    }
330
331    // ================================================================
332    //  Document-enum setters forward to the V0 variant.
333    // ================================================================
334
335    #[test]
336    fn setters_forward_all_fields_to_v0() {
337        let mut doc = make_doc();
338        doc.set_id(Identifier::new([42u8; 32]));
339        doc.set_owner_id(Identifier::new([43u8; 32]));
340        let mut p = BTreeMap::new();
341        p.insert("z".into(), Value::Bool(true));
342        doc.set_properties(p.clone());
343        doc.set_revision(Some(99));
344        doc.set_created_at(Some(1_000_000));
345        doc.set_updated_at(Some(2_000_000));
346        doc.set_transferred_at(Some(3_000_000));
347        doc.set_created_at_block_height(Some(111));
348        doc.set_updated_at_block_height(Some(222));
349        doc.set_transferred_at_block_height(Some(333));
350        doc.set_created_at_core_block_height(Some(4));
351        doc.set_updated_at_core_block_height(Some(5));
352        doc.set_transferred_at_core_block_height(Some(6));
353        doc.set_creator_id(Some(Identifier::new([7u8; 32])));
354
355        assert_eq!(doc.id(), Identifier::new([42u8; 32]));
356        assert_eq!(doc.owner_id(), Identifier::new([43u8; 32]));
357        assert_eq!(doc.properties(), &p);
358        assert_eq!(doc.revision(), Some(99));
359        assert_eq!(doc.created_at(), Some(1_000_000));
360        assert_eq!(doc.updated_at(), Some(2_000_000));
361        assert_eq!(doc.transferred_at(), Some(3_000_000));
362        assert_eq!(doc.created_at_block_height(), Some(111));
363        assert_eq!(doc.updated_at_block_height(), Some(222));
364        assert_eq!(doc.transferred_at_block_height(), Some(333));
365        assert_eq!(doc.created_at_core_block_height(), Some(4));
366        assert_eq!(doc.updated_at_core_block_height(), Some(5));
367        assert_eq!(doc.transferred_at_core_block_height(), Some(6));
368        assert_eq!(doc.creator_id(), Some(Identifier::new([7u8; 32])));
369    }
370
371    // ================================================================
372    //  Document-enum bump_revision forwards to the V0 saturating_add.
373    //  Unlike increment_revision, bump_revision never errors and
374    //  saturates at Revision::MAX.
375    // ================================================================
376
377    #[test]
378    fn bump_revision_via_enum_saturates_at_max() {
379        let mut doc = make_doc();
380        doc.set_revision(Some(Revision::MAX));
381        doc.bump_revision();
382        assert_eq!(doc.revision(), Some(Revision::MAX));
383    }
384
385    #[test]
386    fn bump_revision_via_enum_is_noop_for_none() {
387        let mut doc = make_doc();
388        doc.set_revision(None);
389        doc.bump_revision();
390        assert_eq!(doc.revision(), None);
391    }
392
393    // ================================================================
394    //  Document::get (default impl on the trait) returns a property
395    //  at the given path or None.
396    // ================================================================
397
398    #[test]
399    fn get_returns_property_by_path() {
400        let mut doc = make_doc();
401        doc.properties_mut().insert("a".into(), Value::U64(1));
402        assert_eq!(doc.get("a"), Some(&Value::U64(1)));
403        assert_eq!(doc.get("missing"), None);
404    }
405}