dpp/data_contract/accessors/
mod.rs

1use crate::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters};
2use crate::data_contract::config::DataContractConfig;
3use crate::data_contract::document_type::{DocumentType, DocumentTypeRef};
4use crate::data_contract::{
5    DocumentName, GroupContractPosition, TokenContractPosition, EMPTY_GROUPS, EMPTY_TOKENS,
6};
7use crate::prelude::{BlockHeight, DataContract};
8
9use platform_value::Identifier;
10
11use crate::block::epoch::EpochIndex;
12use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1Setters};
13use crate::data_contract::associated_token::token_configuration::TokenConfiguration;
14use crate::data_contract::errors::DataContractError;
15use crate::data_contract::group::Group;
16use crate::identity::TimestampMillis;
17use crate::tokens::errors::TokenError;
18use crate::ProtocolError;
19use std::collections::BTreeMap;
20
21use super::EMPTY_KEYWORDS;
22
23pub mod v0;
24pub mod v1;
25
26impl DataContractV0Getters for DataContract {
27    fn id(&self) -> Identifier {
28        match self {
29            DataContract::V0(v0) => v0.id(),
30            DataContract::V1(v1) => v1.id(),
31        }
32    }
33
34    fn id_ref(&self) -> &Identifier {
35        match self {
36            DataContract::V0(v0) => v0.id_ref(),
37            DataContract::V1(v1) => v1.id_ref(),
38        }
39    }
40
41    fn system_version_type(&self) -> u16 {
42        match self {
43            DataContract::V0(_) => 0,
44            DataContract::V1(_) => 1,
45        }
46    }
47
48    fn version(&self) -> u32 {
49        match self {
50            DataContract::V0(v0) => v0.version(),
51            DataContract::V1(v1) => v1.version(),
52        }
53    }
54
55    fn owner_id(&self) -> Identifier {
56        match self {
57            DataContract::V0(v0) => v0.owner_id(),
58            DataContract::V1(v1) => v1.owner_id(),
59        }
60    }
61
62    fn document_type_cloned_for_name(&self, name: &str) -> Result<DocumentType, DataContractError> {
63        match self {
64            DataContract::V0(v0) => v0.document_type_cloned_for_name(name),
65            DataContract::V1(v1) => v1.document_type_cloned_for_name(name),
66        }
67    }
68
69    fn document_type_borrowed_for_name(
70        &self,
71        name: &str,
72    ) -> Result<&DocumentType, DataContractError> {
73        match self {
74            DataContract::V0(v0) => v0.document_type_borrowed_for_name(name),
75            DataContract::V1(v1) => v1.document_type_borrowed_for_name(name),
76        }
77    }
78
79    fn document_type_for_name(&self, name: &str) -> Result<DocumentTypeRef<'_>, DataContractError> {
80        match self {
81            DataContract::V0(v0) => v0.document_type_for_name(name),
82            DataContract::V1(v1) => v1.document_type_for_name(name),
83        }
84    }
85
86    fn document_type_optional_for_name(&self, name: &str) -> Option<DocumentTypeRef<'_>> {
87        match self {
88            DataContract::V0(v0) => v0.document_type_optional_for_name(name),
89            DataContract::V1(v1) => v1.document_type_optional_for_name(name),
90        }
91    }
92
93    fn document_type_cloned_optional_for_name(&self, name: &str) -> Option<DocumentType> {
94        match self {
95            DataContract::V0(v0) => v0.document_type_cloned_optional_for_name(name),
96            DataContract::V1(v1) => v1.document_type_cloned_optional_for_name(name),
97        }
98    }
99
100    fn has_document_type_for_name(&self, name: &str) -> bool {
101        match self {
102            DataContract::V0(v0) => v0.has_document_type_for_name(name),
103            DataContract::V1(v1) => v1.has_document_type_for_name(name),
104        }
105    }
106
107    fn document_types_with_contested_indexes(&self) -> BTreeMap<&DocumentName, &DocumentType> {
108        match self {
109            DataContract::V0(v0) => v0.document_types_with_contested_indexes(),
110            DataContract::V1(v1) => v1.document_types_with_contested_indexes(),
111        }
112    }
113
114    fn document_types(&self) -> &BTreeMap<DocumentName, DocumentType> {
115        match self {
116            DataContract::V0(v0) => v0.document_types(),
117            DataContract::V1(v1) => v1.document_types(),
118        }
119    }
120
121    fn document_types_mut(&mut self) -> &mut BTreeMap<DocumentName, DocumentType> {
122        match self {
123            DataContract::V0(v0) => v0.document_types_mut(),
124            DataContract::V1(v1) => v1.document_types_mut(),
125        }
126    }
127
128    fn config(&self) -> &DataContractConfig {
129        match self {
130            DataContract::V0(v0) => v0.config(),
131            DataContract::V1(v1) => v1.config(),
132        }
133    }
134
135    fn config_mut(&mut self) -> &mut DataContractConfig {
136        match self {
137            DataContract::V0(v0) => v0.config_mut(),
138            DataContract::V1(v1) => v1.config_mut(),
139        }
140    }
141}
142
143impl DataContractV0Setters for DataContract {
144    fn set_id(&mut self, id: Identifier) {
145        match self {
146            DataContract::V0(v0) => v0.set_id(id),
147            DataContract::V1(v1) => v1.set_id(id),
148        }
149    }
150
151    fn set_version(&mut self, version: u32) {
152        match self {
153            DataContract::V0(v0) => v0.set_version(version),
154            DataContract::V1(v1) => v1.set_version(version),
155        }
156    }
157
158    fn increment_version(&mut self) {
159        match self {
160            DataContract::V0(v0) => v0.increment_version(),
161            DataContract::V1(v1) => v1.increment_version(),
162        }
163    }
164
165    fn set_owner_id(&mut self, owner_id: Identifier) {
166        match self {
167            DataContract::V0(v0) => v0.set_owner_id(owner_id),
168            DataContract::V1(v1) => v1.set_owner_id(owner_id),
169        }
170    }
171
172    fn set_config(&mut self, config: DataContractConfig) {
173        match self {
174            DataContract::V0(v0) => v0.set_config(config),
175            DataContract::V1(v1) => v1.set_config(config),
176        }
177    }
178}
179
180/// Implementing DataContractV1Getters for DataContract
181impl DataContractV1Getters for DataContract {
182    /// Returns a reference to the groups map.
183    fn groups(&self) -> &BTreeMap<GroupContractPosition, Group> {
184        match self {
185            DataContract::V0(_) => &EMPTY_GROUPS,
186            DataContract::V1(v1) => &v1.groups,
187        }
188    }
189
190    /// Returns a mutable reference to the groups map.
191    /// Returns `None` for V0 since it doesn't have groups.
192    fn groups_mut(&mut self) -> Option<&mut BTreeMap<GroupContractPosition, Group>> {
193        match self {
194            DataContract::V0(_) => None,
195            DataContract::V1(v1) => Some(&mut v1.groups),
196        }
197    }
198
199    /// Returns a reference to a group or an error.
200    /// Returns an Error for V0 since it doesn't have groups.
201    fn expected_group(&self, position: GroupContractPosition) -> Result<&Group, ProtocolError> {
202        match self {
203            DataContract::V0(_) => Err(ProtocolError::GroupNotFound(
204                "Group not found in contract V0".to_string(),
205            )),
206            DataContract::V1(v1) => {
207                v1.groups
208                    .get(&position)
209                    .ok_or(ProtocolError::GroupNotFound(format!(
210                        "Group not found at position {} in contract {}",
211                        position,
212                        self.id()
213                    )))
214            }
215        }
216    }
217
218    /// Returns a reference to the tokens map.
219    fn tokens(&self) -> &BTreeMap<TokenContractPosition, TokenConfiguration> {
220        match self {
221            DataContract::V0(_) => &EMPTY_TOKENS,
222            DataContract::V1(v1) => &v1.tokens,
223        }
224    }
225
226    /// Returns a mutable reference to the tokens map.
227    /// Returns `None` for V0 since it doesn't have tokens.
228    fn tokens_mut(&mut self) -> Option<&mut BTreeMap<TokenContractPosition, TokenConfiguration>> {
229        match self {
230            DataContract::V0(_) => None,
231            DataContract::V1(v1) => Some(&mut v1.tokens),
232        }
233    }
234
235    /// Returns a mutable reference to a token configuration or an error.
236    /// Returns an Error for V0 since it doesn't have tokens.
237    fn expected_token_configuration(
238        &self,
239        position: TokenContractPosition,
240    ) -> Result<&TokenConfiguration, ProtocolError> {
241        match self {
242            DataContract::V0(_) => Err(ProtocolError::Token(
243                TokenError::TokenNotFoundOnContractVersion.into(),
244            )),
245            DataContract::V1(v1) => v1.tokens.get(&position).ok_or(ProtocolError::Token(
246                TokenError::TokenNotFoundAtPositionError.into(),
247            )),
248        }
249    }
250
251    /// Returns a mutable reference to a token configuration
252    /// Returns `None` for V0 since it doesn't have tokens.
253    fn token_configuration_mut(
254        &mut self,
255        position: TokenContractPosition,
256    ) -> Option<&mut TokenConfiguration> {
257        match self {
258            DataContract::V0(_) => None,
259            DataContract::V1(v1) => v1.tokens.get_mut(&position),
260        }
261    }
262
263    fn token_id(&self, position: TokenContractPosition) -> Option<Identifier> {
264        match self {
265            DataContract::V0(_) => None,
266            DataContract::V1(v1) => v1.token_id(position),
267        }
268    }
269
270    fn keywords(&self) -> &Vec<String> {
271        match self {
272            DataContract::V0(_) => &EMPTY_KEYWORDS,
273            DataContract::V1(v1) => &v1.keywords,
274        }
275    }
276
277    fn keywords_mut(&mut self) -> Option<&mut Vec<String>> {
278        match self {
279            DataContract::V0(_) => None,
280            DataContract::V1(v1) => Some(&mut v1.keywords),
281        }
282    }
283
284    fn description(&self) -> Option<&String> {
285        match self {
286            DataContract::V0(_) => None,
287            DataContract::V1(v1) => v1.description.as_ref(),
288        }
289    }
290
291    fn description_mut(&mut self) -> Option<&mut String> {
292        match self {
293            DataContract::V0(_) => None,
294            DataContract::V1(v1) => v1.description.as_mut(),
295        }
296    }
297
298    /// Returns the timestamp in milliseconds when the contract was created.
299    fn created_at(&self) -> Option<TimestampMillis> {
300        match self {
301            DataContract::V0(_) => None,
302            DataContract::V1(v1) => v1.created_at,
303        }
304    }
305
306    /// Returns the timestamp in milliseconds when the contract was last updated.
307    fn updated_at(&self) -> Option<TimestampMillis> {
308        match self {
309            DataContract::V0(_) => None,
310            DataContract::V1(v1) => v1.updated_at,
311        }
312    }
313
314    /// Returns the block height at which the contract was created.
315    fn created_at_block_height(&self) -> Option<BlockHeight> {
316        match self {
317            DataContract::V0(_) => None,
318            DataContract::V1(v1) => v1.created_at_block_height,
319        }
320    }
321
322    /// Returns the block height at which the contract was last updated.
323    fn updated_at_block_height(&self) -> Option<BlockHeight> {
324        match self {
325            DataContract::V0(_) => None,
326            DataContract::V1(v1) => v1.updated_at_block_height,
327        }
328    }
329
330    /// Returns the epoch at which the contract was created.
331    fn created_at_epoch(&self) -> Option<EpochIndex> {
332        match self {
333            DataContract::V0(_) => None,
334            DataContract::V1(v1) => v1.created_at_epoch,
335        }
336    }
337
338    /// Returns the epoch at which the contract was last updated.
339    fn updated_at_epoch(&self) -> Option<EpochIndex> {
340        match self {
341            DataContract::V0(_) => None,
342            DataContract::V1(v1) => v1.updated_at_epoch,
343        }
344    }
345}
346
347impl DataContractV1Setters for DataContract {
348    /// Sets the groups map for the data contract.
349    fn set_groups(&mut self, groups: BTreeMap<GroupContractPosition, Group>) {
350        match self {
351            DataContract::V0(_) => {}
352            DataContract::V1(v1) => {
353                v1.groups = groups;
354            }
355        }
356    }
357
358    /// Sets the tokens map for the data contract.
359    fn set_tokens(&mut self, tokens: BTreeMap<TokenContractPosition, TokenConfiguration>) {
360        match self {
361            DataContract::V0(_) => {}
362            DataContract::V1(v1) => {
363                v1.tokens = tokens;
364            }
365        }
366    }
367
368    /// Adds or updates a single group in the groups map.
369    fn add_group(&mut self, position: GroupContractPosition, group: Group) {
370        match self {
371            DataContract::V0(_) => {}
372            DataContract::V1(v1) => {
373                v1.groups.insert(position, group);
374            }
375        }
376    }
377
378    /// Adds or updates a single token configuration in the tokens map.
379    fn add_token(&mut self, id: TokenContractPosition, token: TokenConfiguration) {
380        match self {
381            DataContract::V0(_) => {}
382            DataContract::V1(v1) => {
383                v1.tokens.insert(id, token);
384            }
385        }
386    }
387
388    /// Sets the timestamp in milliseconds when the contract was created.
389    fn set_created_at(&mut self, created_at: Option<TimestampMillis>) {
390        if let DataContract::V1(v1) = self {
391            v1.created_at = created_at;
392        }
393    }
394
395    /// Sets the timestamp in milliseconds when the contract was last updated.
396    fn set_updated_at(&mut self, updated_at: Option<TimestampMillis>) {
397        if let DataContract::V1(v1) = self {
398            v1.updated_at = updated_at;
399        }
400    }
401
402    /// Sets the block height at which the contract was created.
403    fn set_created_at_block_height(&mut self, block_height: Option<BlockHeight>) {
404        if let DataContract::V1(v1) = self {
405            v1.created_at_block_height = block_height;
406        }
407    }
408
409    /// Sets the block height at which the contract was last updated.
410    fn set_updated_at_block_height(&mut self, block_height: Option<BlockHeight>) {
411        if let DataContract::V1(v1) = self {
412            v1.updated_at_block_height = block_height;
413        }
414    }
415
416    /// Sets the epoch at which the contract was created.
417    fn set_created_at_epoch(&mut self, epoch: Option<EpochIndex>) {
418        if let DataContract::V1(v1) = self {
419            v1.created_at_epoch = epoch;
420        }
421    }
422
423    /// Sets the epoch at which the contract was last updated.
424    fn set_updated_at_epoch(&mut self, epoch: Option<EpochIndex>) {
425        if let DataContract::V1(v1) = self {
426            v1.updated_at_epoch = epoch;
427        }
428    }
429
430    /// Sets the keywords for the contract.
431    fn set_keywords(&mut self, keywords: Vec<String>) {
432        if let DataContract::V1(v1) = self {
433            v1.keywords = keywords;
434        }
435    }
436
437    /// Sets the description for the contract.
438    fn set_description(&mut self, description: Option<String>) {
439        if let DataContract::V1(v1) = self {
440            v1.description = description;
441        }
442    }
443}