dpp/data_contract/v1/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::errors::DataContractError;
5
6use crate::data_contract::v1::DataContractV1;
7use crate::data_contract::{DocumentName, GroupContractPosition, TokenContractPosition};
8
9use crate::block::epoch::EpochIndex;
10use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1Setters};
11use crate::data_contract::associated_token::token_configuration::TokenConfiguration;
12use crate::data_contract::document_type::accessors::{
13    DocumentTypeV0Getters, DocumentTypeV0Setters,
14};
15use crate::data_contract::group::Group;
16use crate::identity::TimestampMillis;
17use crate::prelude::BlockHeight;
18use crate::tokens::calculate_token_id;
19use crate::tokens::errors::TokenError;
20use crate::ProtocolError;
21use platform_value::Identifier;
22use std::collections::BTreeMap;
23
24impl DataContractV0Getters for DataContractV1 {
25    fn id(&self) -> Identifier {
26        self.id
27    }
28
29    fn id_ref(&self) -> &Identifier {
30        &self.id
31    }
32
33    fn system_version_type(&self) -> u16 {
34        1
35    }
36
37    fn version(&self) -> u32 {
38        self.version
39    }
40
41    fn owner_id(&self) -> Identifier {
42        self.owner_id
43    }
44
45    fn document_type_cloned_for_name(&self, name: &str) -> Result<DocumentType, DataContractError> {
46        self.document_type_cloned_optional_for_name(name)
47            .ok_or_else(|| {
48                DataContractError::DocumentTypeNotFound(
49                    "can not get document type from contract".to_string(),
50                )
51            })
52    }
53
54    fn document_type_borrowed_for_name(
55        &self,
56        name: &str,
57    ) -> Result<&DocumentType, DataContractError> {
58        self.document_types.get(name).ok_or_else(|| {
59            DataContractError::DocumentTypeNotFound(
60                "can not get document type from contract".to_string(),
61            )
62        })
63    }
64
65    fn document_type_for_name(&self, name: &str) -> Result<DocumentTypeRef<'_>, DataContractError> {
66        self.document_type_optional_for_name(name).ok_or_else(|| {
67            DataContractError::DocumentTypeNotFound(
68                "can not get document type from contract".to_string(),
69            )
70        })
71    }
72
73    fn document_type_optional_for_name(&self, name: &str) -> Option<DocumentTypeRef<'_>> {
74        self.document_types
75            .get(name)
76            .map(|document_type| document_type.as_ref())
77    }
78
79    fn document_type_cloned_optional_for_name(&self, name: &str) -> Option<DocumentType> {
80        self.document_types.get(name).cloned()
81    }
82
83    fn has_document_type_for_name(&self, name: &str) -> bool {
84        self.document_types.contains_key(name)
85    }
86
87    fn document_types_with_contested_indexes(&self) -> BTreeMap<&DocumentName, &DocumentType> {
88        self.document_types
89            .iter()
90            .filter(|(_, document_type)| {
91                document_type
92                    .indexes()
93                    .iter()
94                    .any(|(_, index)| index.contested_index.is_some())
95            })
96            .collect()
97    }
98
99    fn document_types(&self) -> &BTreeMap<DocumentName, DocumentType> {
100        &self.document_types
101    }
102
103    fn document_types_mut(&mut self) -> &mut BTreeMap<DocumentName, DocumentType> {
104        &mut self.document_types
105    }
106
107    fn config(&self) -> &DataContractConfig {
108        &self.config
109    }
110
111    fn config_mut(&mut self) -> &mut DataContractConfig {
112        &mut self.config
113    }
114}
115
116impl DataContractV0Setters for DataContractV1 {
117    fn set_id(&mut self, id: Identifier) {
118        self.id = id;
119
120        self.document_types
121            .iter_mut()
122            .for_each(|(_, document_type)| document_type.set_data_contract_id(id))
123    }
124
125    fn set_version(&mut self, version: u32) {
126        self.version = version;
127    }
128
129    fn increment_version(&mut self) {
130        self.version += 1;
131    }
132
133    fn set_owner_id(&mut self, owner_id: Identifier) {
134        self.owner_id = owner_id;
135    }
136
137    fn set_config(&mut self, config: DataContractConfig) {
138        self.config = config;
139    }
140}
141
142impl DataContractV1Getters for DataContractV1 {
143    fn groups(&self) -> &BTreeMap<GroupContractPosition, Group> {
144        &self.groups
145    }
146
147    fn groups_mut(&mut self) -> Option<&mut BTreeMap<GroupContractPosition, Group>> {
148        Some(&mut self.groups)
149    }
150
151    fn expected_group(&self, position: GroupContractPosition) -> Result<&Group, ProtocolError> {
152        self.groups
153            .get(&position)
154            .ok_or(ProtocolError::GroupNotFound(format!(
155                "Group not found at position {} in contract {}",
156                position,
157                self.id()
158            )))
159    }
160
161    fn tokens(&self) -> &BTreeMap<TokenContractPosition, TokenConfiguration> {
162        &self.tokens
163    }
164
165    fn tokens_mut(&mut self) -> Option<&mut BTreeMap<TokenContractPosition, TokenConfiguration>> {
166        Some(&mut self.tokens)
167    }
168
169    fn expected_token_configuration(
170        &self,
171        position: TokenContractPosition,
172    ) -> Result<&TokenConfiguration, ProtocolError> {
173        self.tokens.get(&position).ok_or(ProtocolError::Token(
174            TokenError::TokenNotFoundAtPositionError.into(),
175        ))
176    }
177
178    fn token_configuration_mut(
179        &mut self,
180        position: TokenContractPosition,
181    ) -> Option<&mut TokenConfiguration> {
182        self.tokens.get_mut(&position)
183    }
184
185    /// Returns the token id if a token exists at that position
186    fn token_id(&self, position: TokenContractPosition) -> Option<Identifier> {
187        self.tokens
188            .get(&position)
189            .map(|_| calculate_token_id(self.id.as_bytes(), position).into())
190    }
191
192    /// Returns the timestamp in milliseconds when the contract was created.
193    fn created_at(&self) -> Option<TimestampMillis> {
194        self.created_at
195    }
196
197    /// Returns the timestamp in milliseconds when the contract was last updated.
198    fn updated_at(&self) -> Option<TimestampMillis> {
199        self.updated_at
200    }
201
202    /// Returns the block height at which the contract was created.
203    fn created_at_block_height(&self) -> Option<BlockHeight> {
204        self.created_at_block_height
205    }
206
207    /// Returns the block height at which the contract was last updated.
208    fn updated_at_block_height(&self) -> Option<BlockHeight> {
209        self.updated_at_block_height
210    }
211
212    /// Returns the epoch at which the contract was created.
213    fn created_at_epoch(&self) -> Option<EpochIndex> {
214        self.created_at_epoch
215    }
216
217    /// Returns the epoch at which the contract was last updated.
218    fn updated_at_epoch(&self) -> Option<EpochIndex> {
219        self.updated_at_epoch
220    }
221
222    /// Returns the keywords for the contract.
223    fn keywords(&self) -> &Vec<String> {
224        &self.keywords
225    }
226
227    /// Returns a mutable reference to the keywords for the contract.
228    fn keywords_mut(&mut self) -> Option<&mut Vec<String>> {
229        Some(&mut self.keywords)
230    }
231
232    /// Returns the description of the contract.
233    fn description(&self) -> Option<&String> {
234        self.description.as_ref()
235    }
236
237    /// Returns a mutable reference to the description of the contract.
238    fn description_mut(&mut self) -> Option<&mut String> {
239        self.description.as_mut()
240    }
241}
242
243impl DataContractV1Setters for DataContractV1 {
244    fn set_groups(&mut self, groups: BTreeMap<GroupContractPosition, Group>) {
245        self.groups = groups;
246    }
247
248    fn set_tokens(&mut self, tokens: BTreeMap<TokenContractPosition, TokenConfiguration>) {
249        self.tokens = tokens;
250    }
251
252    fn add_group(&mut self, group_position: GroupContractPosition, group: Group) {
253        self.groups.insert(group_position, group);
254    }
255
256    fn add_token(&mut self, name: TokenContractPosition, token: TokenConfiguration) {
257        self.tokens.insert(name, token);
258    }
259
260    /// Sets the timestamp in milliseconds when the contract was created.
261    fn set_created_at(&mut self, created_at: Option<TimestampMillis>) {
262        self.created_at = created_at;
263    }
264
265    /// Sets the timestamp in milliseconds when the contract was last updated.
266    fn set_updated_at(&mut self, updated_at: Option<TimestampMillis>) {
267        self.updated_at = updated_at;
268    }
269
270    /// Sets the block height at which the contract was created.
271    fn set_created_at_block_height(&mut self, block_height: Option<BlockHeight>) {
272        self.created_at_block_height = block_height;
273    }
274
275    /// Sets the block height at which the contract was last updated.
276    fn set_updated_at_block_height(&mut self, block_height: Option<BlockHeight>) {
277        self.updated_at_block_height = block_height;
278    }
279
280    /// Sets the epoch at which the contract was created.
281    fn set_created_at_epoch(&mut self, epoch: Option<EpochIndex>) {
282        self.created_at_epoch = epoch;
283    }
284
285    /// Sets the epoch at which the contract was last updated.
286    fn set_updated_at_epoch(&mut self, epoch: Option<EpochIndex>) {
287        self.updated_at_epoch = epoch;
288    }
289
290    /// Sets the keywords for the contract.
291    fn set_keywords(&mut self, keywords: Vec<String>) {
292        self.keywords = keywords;
293    }
294
295    /// Sets the description for the contract.
296    fn set_description(&mut self, description: Option<String>) {
297        self.description = description;
298    }
299}