1use crate::errors::ProtocolError;
2use bincode::{Decode, Encode};
3use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
4use thiserror::Error;
5
6use crate::consensus::state::address_funds::{AddressDoesNotExistError, AddressInvalidNonceError, AddressNotEnoughFundsError, AddressesNotEnoughFundsError};
7use crate::consensus::state::shielded::insufficient_pool_notes_error::InsufficientPoolNotesError;
8use crate::consensus::state::shielded::insufficient_shielded_fee_error::InsufficientShieldedFeeError;
9use crate::consensus::state::shielded::invalid_anchor_error::InvalidAnchorError;
10use crate::consensus::state::shielded::invalid_shielded_proof_error::InvalidShieldedProofError;
11use crate::consensus::state::shielded::nullifier_already_spent_error::NullifierAlreadySpentError;
12use crate::consensus::state::data_contract::data_contract_already_present_error::DataContractAlreadyPresentError;
13use crate::consensus::state::data_contract::data_contract_config_update_error::DataContractConfigUpdateError;
14use crate::consensus::state::data_contract::data_contract_is_readonly_error::DataContractIsReadonlyError;
15use crate::consensus::state::data_trigger::DataTriggerError;
16use crate::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError;
17use crate::consensus::state::document::document_not_found_error::DocumentNotFoundError;
18use crate::consensus::state::document::document_owner_id_mismatch_error::DocumentOwnerIdMismatchError;
19use crate::consensus::state::document::document_timestamp_window_violation_error::DocumentTimestampWindowViolationError;
20use crate::consensus::state::document::document_timestamps_mismatch_error::DocumentTimestampsMismatchError;
21use crate::consensus::state::document::duplicate_unique_index_error::DuplicateUniqueIndexError;
22use crate::consensus::state::document::invalid_document_revision_error::InvalidDocumentRevisionError;
23use crate::consensus::state::identity::duplicated_identity_public_key_id_state_error::DuplicatedIdentityPublicKeyIdStateError;
24use crate::consensus::state::identity::duplicated_identity_public_key_state_error::DuplicatedIdentityPublicKeyStateError;
25use crate::consensus::state::identity::identity_public_key_is_disabled_error::IdentityPublicKeyIsDisabledError;
26use crate::consensus::state::identity::identity_public_key_is_read_only_error::IdentityPublicKeyIsReadOnlyError;
27use crate::consensus::state::identity::invalid_identity_public_key_id_error::InvalidIdentityPublicKeyIdError;
28use crate::consensus::state::identity::invalid_identity_revision_error::InvalidIdentityRevisionError;
29use crate::consensus::state::identity::max_identity_public_key_limit_reached_error::MaxIdentityPublicKeyLimitReachedError;
30use crate::consensus::state::identity::missing_identity_public_key_ids_error::MissingIdentityPublicKeyIdsError;
31use crate::consensus::state::identity::{IdentityAlreadyExistsError, IdentityInsufficientBalanceError, RecipientIdentityDoesNotExistError};
32use crate::consensus::ConsensusError;
33use crate::consensus::state::data_contract::data_contract_not_found_error::DataContractNotFoundError;
34use crate::consensus::state::data_contract::data_contract_update_action_not_allowed_error::DataContractUpdateActionNotAllowedError;
35use crate::consensus::state::data_contract::data_contract_update_permission_error::DataContractUpdatePermissionError;
36use crate::consensus::state::data_contract::document_type_update_error::DocumentTypeUpdateError;
37use crate::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError;
38use crate::consensus::state::document::document_contest_document_with_same_id_already_present_error::DocumentContestDocumentWithSameIdAlreadyPresentError;
39use crate::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError;
40use crate::consensus::state::document::document_contest_index_mismatch_error::DocumentContestIndexMismatchError;
41use crate::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError;
42use crate::consensus::state::document::document_contest_not_paid_for_error::DocumentContestNotPaidForError;
43use crate::consensus::state::document::document_contest_not_required_error::DocumentContestNotRequiredError;
44use crate::consensus::state::document::referenced_document_type_deletable_error::ReferencedDocumentTypeDeletableError;
45use crate::consensus::state::document::referenced_document_type_not_found_error::ReferencedDocumentTypeNotFoundError;
46use crate::consensus::state::document::referenced_entity_not_found_error::ReferencedEntityNotFoundError;
47use crate::consensus::state::document::referenced_identity_key_disabled_error::ReferencedIdentityKeyDisabledError;
48use crate::consensus::state::document::referenced_identity_key_not_found_error::ReferencedIdentityKeyNotFoundError;
49use crate::consensus::state::document::referenced_document_property_agreement_invalid_error::ReferencedDocumentPropertyAgreementInvalidError;
50use crate::consensus::state::document::referenced_document_property_mismatch_error::ReferencedDocumentPropertyMismatchError;
51use crate::consensus::state::document::referenced_key_id_property_invalid_error::ReferencedKeyIdPropertyInvalidError;
52use crate::consensus::state::document::document_incorrect_purchase_price_error::DocumentIncorrectPurchasePriceError;
53use crate::consensus::state::document::document_not_for_sale_error::DocumentNotForSaleError;
54use crate::consensus::state::group::{GroupActionAlreadyCompletedError, GroupActionAlreadySignedByIdentityError, GroupActionDoesNotExistError, IdentityMemberOfGroupNotFoundError, IdentityNotMemberOfGroupError, ModificationOfGroupActionMainParametersNotPermittedError};
55use crate::consensus::state::identity::identity_for_token_configuration_not_found_error::IdentityInTokenConfigurationNotFoundError;
56use crate::consensus::state::identity::identity_public_key_already_exists_for_unique_contract_bounds_error::IdentityPublicKeyAlreadyExistsForUniqueContractBoundsError;
57use crate::consensus::state::identity::identity_to_freeze_does_not_exist_error::IdentityToFreezeDoesNotExistError;
58use crate::consensus::state::identity::invalid_identity_contract_nonce_error::InvalidIdentityNonceError;
59use crate::consensus::state::identity::missing_transfer_key_error::MissingTransferKeyError;
60use crate::consensus::state::identity::no_transfer_key_for_core_withdrawal_available_error::NoTransferKeyForCoreWithdrawalAvailableError;
61use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_insufficient_error::PrefundedSpecializedBalanceInsufficientError;
62use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_not_found_error::PrefundedSpecializedBalanceNotFoundError;
63use crate::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, IdentityTokenAccountFrozenError, IdentityTokenAccountNotFrozenError, InvalidGroupPositionError, NewAuthorizedActionTakerGroupDoesNotExistError, NewAuthorizedActionTakerIdentityDoesNotExistError, NewAuthorizedActionTakerMainGroupNotSetError, NewTokensDestinationIdentityDoesNotExistError, TokenMintPastMaxSupplyError, TokenSettingMaxSupplyToLessThanCurrentSupplyError, UnauthorizedTokenActionError, IdentityTokenAccountAlreadyFrozenError, TokenAlreadyPausedError, TokenIsPausedError, TokenNotPausedError, InvalidTokenClaimPropertyMismatch, InvalidTokenClaimNoCurrentRewards, InvalidTokenClaimWrongClaimant, PreProgrammedDistributionTimestampInPastError, TokenTransferRecipientIdentityNotExistError, IdentityHasNotAgreedToPayRequiredTokenAmountError, RequiredTokenPaymentInfoNotSetError, IdentityTryingToPayWithWrongTokenError, TokenDirectPurchaseUserPriceTooLow, TokenAmountUnderMinimumSaleAmount, TokenNotForDirectSale, InvalidTokenPositionStateError};
64use crate::consensus::state::voting::masternode_incorrect_voter_identity_id_error::MasternodeIncorrectVoterIdentityIdError;
65use crate::consensus::state::voting::masternode_incorrect_voting_address_error::MasternodeIncorrectVotingAddressError;
66use crate::consensus::state::voting::masternode_not_found_error::MasternodeNotFoundError;
67use crate::consensus::state::voting::masternode_vote_already_present_error::MasternodeVoteAlreadyPresentError;
68use crate::consensus::state::voting::masternode_voted_too_many_times::MasternodeVotedTooManyTimesError;
69use crate::consensus::state::voting::vote_poll_not_available_for_voting_error::VotePollNotAvailableForVotingError;
70use crate::consensus::state::voting::vote_poll_not_found_error::VotePollNotFoundError;
71
72use super::document::document_timestamps_are_equal_error::DocumentTimestampsAreEqualError;
73
74#[derive(
75 Error, Debug, PartialEq, Encode, Decode, PlatformSerialize, PlatformDeserialize, Clone,
76)]
77pub enum StateError {
78 #[error(transparent)]
84 DataContractAlreadyPresentError(DataContractAlreadyPresentError),
85
86 #[error(transparent)]
87 DataTriggerError(DataTriggerError),
88
89 #[error(transparent)]
90 DocumentAlreadyPresentError(DocumentAlreadyPresentError),
91
92 #[error(transparent)]
93 DocumentContestCurrentlyLockedError(DocumentContestCurrentlyLockedError),
94
95 #[error(transparent)]
96 DocumentContestNotJoinableError(DocumentContestNotJoinableError),
97
98 #[error(transparent)]
99 DocumentContestIdentityAlreadyContestantError(DocumentContestIdentityAlreadyContestantError),
100
101 #[error(transparent)]
102 DocumentContestNotPaidForError(DocumentContestNotPaidForError),
103
104 #[error(transparent)]
105 DocumentContestDocumentWithSameIdAlreadyPresentError(
106 DocumentContestDocumentWithSameIdAlreadyPresentError,
107 ),
108
109 #[error(transparent)]
110 DocumentNotFoundError(DocumentNotFoundError),
111
112 #[error(transparent)]
113 DocumentNotForSaleError(DocumentNotForSaleError),
114
115 #[error(transparent)]
116 DocumentIncorrectPurchasePriceError(DocumentIncorrectPurchasePriceError),
117
118 #[error(transparent)]
119 DocumentOwnerIdMismatchError(DocumentOwnerIdMismatchError),
120
121 #[error(transparent)]
122 DocumentTimestampsMismatchError(DocumentTimestampsMismatchError),
123
124 #[error(transparent)]
125 DocumentTimestampWindowViolationError(DocumentTimestampWindowViolationError),
126
127 #[error(transparent)]
128 DuplicateUniqueIndexError(DuplicateUniqueIndexError),
129
130 #[error(transparent)]
131 InvalidDocumentRevisionError(InvalidDocumentRevisionError),
132
133 #[error(transparent)]
134 IdentityAlreadyExistsError(IdentityAlreadyExistsError),
135
136 #[error(transparent)]
137 IdentityPublicKeyAlreadyExistsForUniqueContractBoundsError(
138 IdentityPublicKeyAlreadyExistsForUniqueContractBoundsError,
139 ),
140
141 #[error(transparent)]
142 IdentityPublicKeyIsReadOnlyError(IdentityPublicKeyIsReadOnlyError),
143
144 #[error(transparent)]
145 MissingIdentityPublicKeyIdsError(MissingIdentityPublicKeyIdsError),
146
147 #[error(transparent)]
148 MissingTransferKeyError(MissingTransferKeyError),
149
150 #[error(transparent)]
151 NoTransferKeyForCoreWithdrawalAvailableError(NoTransferKeyForCoreWithdrawalAvailableError),
152
153 #[error(transparent)]
154 InvalidIdentityPublicKeyIdError(InvalidIdentityPublicKeyIdError),
155
156 #[error(transparent)]
157 InvalidIdentityRevisionError(InvalidIdentityRevisionError),
158
159 #[error(transparent)]
160 InvalidIdentityNonceError(InvalidIdentityNonceError),
161
162 #[error(transparent)]
163 MaxIdentityPublicKeyLimitReachedError(MaxIdentityPublicKeyLimitReachedError),
164
165 #[error(transparent)]
166 DuplicatedIdentityPublicKeyStateError(DuplicatedIdentityPublicKeyStateError),
167
168 #[error(transparent)]
169 DuplicatedIdentityPublicKeyIdStateError(DuplicatedIdentityPublicKeyIdStateError),
170
171 #[error(transparent)]
172 IdentityPublicKeyIsDisabledError(IdentityPublicKeyIsDisabledError),
173
174 #[error(transparent)]
175 IdentityInsufficientBalanceError(IdentityInsufficientBalanceError),
176
177 #[error(transparent)]
178 DocumentTimestampsAreEqualError(DocumentTimestampsAreEqualError),
179
180 #[error(transparent)]
181 DataContractIsReadonlyError(DataContractIsReadonlyError),
182
183 #[error(transparent)]
184 DataContractConfigUpdateError(DataContractConfigUpdateError),
185
186 #[error(transparent)]
187 DocumentTypeUpdateError(DocumentTypeUpdateError),
188
189 #[error(transparent)]
190 PrefundedSpecializedBalanceInsufficientError(PrefundedSpecializedBalanceInsufficientError),
191
192 #[error(transparent)]
193 PrefundedSpecializedBalanceNotFoundError(PrefundedSpecializedBalanceNotFoundError),
194
195 #[error(transparent)]
196 DataContractUpdatePermissionError(DataContractUpdatePermissionError),
197
198 #[error(transparent)]
199 MasternodeNotFoundError(MasternodeNotFoundError),
200
201 #[error(transparent)]
202 MasternodeIncorrectVoterIdentityIdError(MasternodeIncorrectVoterIdentityIdError),
203
204 #[error(transparent)]
205 MasternodeIncorrectVotingAddressError(MasternodeIncorrectVotingAddressError),
206
207 #[error(transparent)]
208 VotePollNotFoundError(VotePollNotFoundError),
209
210 #[error(transparent)]
211 VotePollNotAvailableForVotingError(VotePollNotAvailableForVotingError),
212
213 #[error(transparent)]
214 MasternodeVotedTooManyTimesError(MasternodeVotedTooManyTimesError),
215
216 #[error(transparent)]
217 MasternodeVoteAlreadyPresentError(MasternodeVoteAlreadyPresentError),
218
219 #[error(transparent)]
220 RecipientIdentityDoesNotExistError(RecipientIdentityDoesNotExistError),
221
222 #[error(transparent)]
223 IdentityDoesNotHaveEnoughTokenBalanceError(IdentityDoesNotHaveEnoughTokenBalanceError),
224
225 #[error(transparent)]
226 UnauthorizedTokenActionError(UnauthorizedTokenActionError),
227
228 #[error(transparent)]
229 IdentityTokenAccountFrozenError(IdentityTokenAccountFrozenError),
230
231 #[error(transparent)]
232 IdentityTokenAccountNotFrozenError(IdentityTokenAccountNotFrozenError),
233
234 #[error(transparent)]
235 IdentityNotMemberOfGroupError(IdentityNotMemberOfGroupError),
236
237 #[error(transparent)]
238 GroupActionDoesNotExistError(GroupActionDoesNotExistError),
239
240 #[error(transparent)]
241 GroupActionAlreadyCompletedError(GroupActionAlreadyCompletedError),
242
243 #[error(transparent)]
244 GroupActionAlreadySignedByIdentityError(GroupActionAlreadySignedByIdentityError),
245
246 #[error(transparent)]
247 DataContractUpdateActionNotAllowedError(DataContractUpdateActionNotAllowedError),
248
249 #[error(transparent)]
250 TokenSettingMaxSupplyToLessThanCurrentSupplyError(
251 TokenSettingMaxSupplyToLessThanCurrentSupplyError,
252 ),
253
254 #[error(transparent)]
255 TokenMintPastMaxSupplyError(TokenMintPastMaxSupplyError),
256
257 #[error(transparent)]
258 InvalidTokenClaimPropertyMismatch(InvalidTokenClaimPropertyMismatch),
259
260 #[error(transparent)]
261 InvalidTokenClaimNoCurrentRewards(InvalidTokenClaimNoCurrentRewards),
262
263 #[error(transparent)]
264 InvalidTokenClaimWrongClaimant(InvalidTokenClaimWrongClaimant),
265
266 #[error(transparent)]
267 NewTokensDestinationIdentityDoesNotExistError(NewTokensDestinationIdentityDoesNotExistError),
268
269 #[error(transparent)]
270 NewAuthorizedActionTakerIdentityDoesNotExistError(
271 NewAuthorizedActionTakerIdentityDoesNotExistError,
272 ),
273
274 #[error(transparent)]
275 NewAuthorizedActionTakerGroupDoesNotExistError(NewAuthorizedActionTakerGroupDoesNotExistError),
276
277 #[error(transparent)]
278 NewAuthorizedActionTakerMainGroupNotSetError(NewAuthorizedActionTakerMainGroupNotSetError),
279
280 #[error(transparent)]
281 InvalidGroupPositionError(InvalidGroupPositionError),
282
283 #[error(transparent)]
284 TokenIsPausedError(TokenIsPausedError),
285
286 #[error(transparent)]
287 IdentityTokenAccountAlreadyFrozenError(IdentityTokenAccountAlreadyFrozenError),
288
289 #[error(transparent)]
290 TokenAlreadyPausedError(TokenAlreadyPausedError),
291
292 #[error(transparent)]
293 TokenNotPausedError(TokenNotPausedError),
294
295 #[error(transparent)]
296 TokenTransferRecipientIdentityNotExistError(TokenTransferRecipientIdentityNotExistError),
297
298 #[error(transparent)]
299 PreProgrammedDistributionTimestampInPastError(PreProgrammedDistributionTimestampInPastError),
300
301 #[error(transparent)]
302 IdentityHasNotAgreedToPayRequiredTokenAmountError(
303 IdentityHasNotAgreedToPayRequiredTokenAmountError,
304 ),
305
306 #[error(transparent)]
307 RequiredTokenPaymentInfoNotSetError(RequiredTokenPaymentInfoNotSetError),
308
309 #[error(transparent)]
310 IdentityTryingToPayWithWrongTokenError(IdentityTryingToPayWithWrongTokenError),
311
312 #[error(transparent)]
313 TokenDirectPurchaseUserPriceTooLow(TokenDirectPurchaseUserPriceTooLow),
314
315 #[error(transparent)]
316 TokenAmountUnderMinimumSaleAmount(TokenAmountUnderMinimumSaleAmount),
317
318 #[error(transparent)]
319 TokenNotForDirectSale(TokenNotForDirectSale),
320
321 #[error(transparent)]
322 IdentityInTokenConfigurationNotFoundError(IdentityInTokenConfigurationNotFoundError),
323
324 #[error(transparent)]
325 IdentityMemberOfGroupNotFoundError(IdentityMemberOfGroupNotFoundError),
326
327 #[error(transparent)]
328 ModificationOfGroupActionMainParametersNotPermittedError(
329 ModificationOfGroupActionMainParametersNotPermittedError,
330 ),
331
332 #[error(transparent)]
333 IdentityToFreezeDoesNotExistError(IdentityToFreezeDoesNotExistError),
334
335 #[error(transparent)]
336 DataContractNotFoundError(DataContractNotFoundError),
337
338 #[error(transparent)]
339 InvalidTokenPositionStateError(InvalidTokenPositionStateError),
340
341 #[error(transparent)]
342 AddressDoesNotExistError(AddressDoesNotExistError),
343
344 #[error(transparent)]
345 AddressNotEnoughFundsError(AddressNotEnoughFundsError),
346
347 #[error(transparent)]
348 AddressesNotEnoughFundsError(AddressesNotEnoughFundsError),
349
350 #[error(transparent)]
351 AddressInvalidNonceError(AddressInvalidNonceError),
352
353 #[error(transparent)]
354 InvalidAnchorError(InvalidAnchorError),
355
356 #[error(transparent)]
357 NullifierAlreadySpentError(NullifierAlreadySpentError),
358
359 #[error(transparent)]
360 InvalidShieldedProofError(InvalidShieldedProofError),
361
362 #[error(transparent)]
363 InsufficientPoolNotesError(InsufficientPoolNotesError),
364
365 #[error(transparent)]
366 InsufficientShieldedFeeError(InsufficientShieldedFeeError),
367
368 #[error(transparent)]
369 DocumentContestIndexMismatchError(DocumentContestIndexMismatchError),
370
371 #[error(transparent)]
372 DocumentContestNotRequiredError(DocumentContestNotRequiredError),
373
374 #[error(transparent)]
375 ReferencedEntityNotFoundError(ReferencedEntityNotFoundError),
376
377 #[error(transparent)]
378 ReferencedDocumentTypeNotFoundError(ReferencedDocumentTypeNotFoundError),
379
380 #[error(transparent)]
381 ReferencedDocumentTypeDeletableError(ReferencedDocumentTypeDeletableError),
382
383 #[error(transparent)]
384 ReferencedIdentityKeyNotFoundError(ReferencedIdentityKeyNotFoundError),
385
386 #[error(transparent)]
387 ReferencedIdentityKeyDisabledError(ReferencedIdentityKeyDisabledError),
388
389 #[error(transparent)]
390 ReferencedKeyIdPropertyInvalidError(ReferencedKeyIdPropertyInvalidError),
391
392 #[error(transparent)]
393 ReferencedDocumentPropertyAgreementInvalidError(
394 ReferencedDocumentPropertyAgreementInvalidError,
395 ),
396
397 #[error(transparent)]
398 ReferencedDocumentPropertyMismatchError(ReferencedDocumentPropertyMismatchError),
399}
400
401impl From<StateError> for ConsensusError {
402 fn from(error: StateError) -> Self {
403 Self::StateError(error)
404 }
405}
406
407#[cfg(test)]
408mod tests {
409 use super::*;
410 use platform_value::Identifier;
411
412 fn discriminant_of(error: StateError) -> u8 {
420 let bytes = bincode::encode_to_vec(error, bincode::config::standard())
421 .expect("expected to encode the state error");
422 bytes[0]
424 }
425
426 #[test]
427 fn state_error_discriminants_are_frozen() {
428 assert_eq!(
429 discriminant_of(StateError::DataContractAlreadyPresentError(
430 DataContractAlreadyPresentError::new(Identifier::from([1; 32]))
431 )),
432 0
433 );
434 assert_eq!(
435 discriminant_of(StateError::DocumentNotFoundError(
436 DocumentNotFoundError::new(Identifier::from([1; 32]))
437 )),
438 8
439 );
440 assert_eq!(
441 discriminant_of(StateError::InsufficientShieldedFeeError(
442 InsufficientShieldedFeeError::new("fee".to_string())
443 )),
444 90
445 );
446 assert_eq!(
447 discriminant_of(StateError::DocumentContestIndexMismatchError(
448 DocumentContestIndexMismatchError::new(
449 Identifier::from([1; 32]),
450 "expected".to_string(),
451 "provided".to_string(),
452 )
453 )),
454 91
455 );
456 assert_eq!(
457 discriminant_of(StateError::DocumentContestNotRequiredError(
458 DocumentContestNotRequiredError::new(
459 Identifier::from([1; 32]),
460 "provided".to_string(),
461 )
462 )),
463 92
464 );
465 assert_eq!(
466 discriminant_of(StateError::ReferencedEntityNotFoundError(
467 ReferencedEntityNotFoundError::new(
468 Identifier::from([1; 32]),
469 crate::data_contract::document_type::DocumentPropertyReferenceTarget::Identity,
470 "toUserId".to_string(),
471 )
472 )),
473 93
474 );
475 assert_eq!(
476 discriminant_of(StateError::ReferencedDocumentTypeNotFoundError(
477 ReferencedDocumentTypeNotFoundError::new(
478 Identifier::from([1; 32]),
479 "note".to_string(),
480 "parentNoteId".to_string(),
481 )
482 )),
483 94
484 );
485 assert_eq!(
486 discriminant_of(StateError::ReferencedDocumentTypeDeletableError(
487 ReferencedDocumentTypeDeletableError::new(
488 Identifier::from([1; 32]),
489 "note".to_string(),
490 "parentNoteId".to_string(),
491 )
492 )),
493 95
494 );
495 assert_eq!(
496 discriminant_of(StateError::ReferencedIdentityKeyNotFoundError(
497 ReferencedIdentityKeyNotFoundError::new(
498 Identifier::from([1; 32]),
499 2,
500 "toUserId".to_string(),
501 )
502 )),
503 96
504 );
505 assert_eq!(
506 discriminant_of(StateError::ReferencedIdentityKeyDisabledError(
507 ReferencedIdentityKeyDisabledError::new(
508 Identifier::from([1; 32]),
509 2,
510 "toUserId".to_string(),
511 )
512 )),
513 97
514 );
515 assert_eq!(
516 discriminant_of(StateError::ReferencedKeyIdPropertyInvalidError(
517 ReferencedKeyIdPropertyInvalidError::new(
518 "recipientKeyIndex".to_string(),
519 "toUserId".to_string(),
520 "missing".to_string(),
521 )
522 )),
523 98
524 );
525 assert_eq!(
526 discriminant_of(StateError::ReferencedDocumentPropertyAgreementInvalidError(
527 ReferencedDocumentPropertyAgreementInvalidError::new(
528 "like.postId".to_string(),
529 "hashtag".to_string(),
530 "hashtag".to_string(),
531 "missing".to_string(),
532 )
533 )),
534 99
535 );
536 assert_eq!(
537 discriminant_of(StateError::ReferencedDocumentPropertyMismatchError(
538 ReferencedDocumentPropertyMismatchError::new(
539 "postId".to_string(),
540 "hashtag".to_string(),
541 "hashtag".to_string(),
542 )
543 )),
544 100
545 );
546 }
547}