radix_common/data/scrypto/
custom_validation.rs1use crate::internal_prelude::*;
2
3impl<'a> ValidatableCustomExtension<()> for ScryptoCustomExtension {
12 fn apply_validation_for_custom_value<'de>(
13 schema: &Schema<Self::CustomSchema>,
14 custom_value: &<Self::CustomTraversal as traversal::CustomTraversal>::CustomTerminalValueRef<'de>,
15 type_id: LocalTypeId,
16 _: &(),
17 ) -> Result<(), PayloadValidationError<Self>> {
18 match schema
19 .resolve_type_validation(type_id)
20 .ok_or(PayloadValidationError::SchemaInconsistency)?
21 {
22 TypeValidation::None => Ok(()),
23 TypeValidation::Custom(custom_validation) => {
24 apply_static_custom_validation_to_custom_value(custom_validation, &custom_value.0)
25 }
26 _ => Err(PayloadValidationError::SchemaInconsistency),
27 }
28 }
29
30 fn apply_custom_type_validation_for_non_custom_value<'de>(
31 _: &Schema<Self::CustomSchema>,
32 _: &<Self::CustomSchema as CustomSchema>::CustomTypeValidation,
33 _: &TerminalValueRef<'de, Self::CustomTraversal>,
34 _: &(),
35 ) -> Result<(), PayloadValidationError<Self>> {
36 Err(PayloadValidationError::SchemaInconsistency)
39 }
40}
41
42fn apply_static_custom_validation_to_custom_value(
43 custom_validation: &ScryptoCustomTypeValidation,
44 custom_value: &ScryptoCustomValue,
45) -> Result<(), PayloadValidationError<ScryptoCustomExtension>> {
46 match custom_validation {
47 ScryptoCustomTypeValidation::Reference(reference_validation) => {
48 let ScryptoCustomValue::Reference(reference) = custom_value else {
49 return Err(PayloadValidationError::SchemaInconsistency);
50 };
51 let node_id = reference.0;
52 let is_valid = match &reference_validation {
53 ReferenceValidation::IsGlobal => node_id.is_global(),
54 ReferenceValidation::IsGlobalPackage => node_id.is_global_package(),
55 ReferenceValidation::IsGlobalComponent => node_id.is_global_component(),
56 ReferenceValidation::IsGlobalResourceManager => {
57 node_id.is_global_resource_manager()
58 }
59 ReferenceValidation::IsGlobalTyped(_, _) => node_id.is_global(),
61 ReferenceValidation::IsInternal => node_id.is_internal(),
62 ReferenceValidation::IsInternalTyped(_, _) => node_id.is_internal(),
64 };
65 if !is_valid {
66 return Err(PayloadValidationError::ValidationError(
67 ValidationError::CustomError(format!(
68 "Expected = Reference<{:?}>, found node id with entity type: {:?}",
69 reference_validation,
70 node_id.entity_type()
71 )),
72 ));
73 }
74 }
75 ScryptoCustomTypeValidation::Own(own_validation) => {
76 let ScryptoCustomValue::Own(own) = custom_value else {
77 return Err(PayloadValidationError::SchemaInconsistency);
78 };
79 let node_id = own.0;
80 let is_valid = match own_validation {
82 OwnValidation::IsBucket => node_id.is_internal(),
83 OwnValidation::IsProof => node_id.is_internal(),
84 OwnValidation::IsVault => node_id.is_internal_vault(),
85 OwnValidation::IsKeyValueStore => node_id.is_internal_kv_store(),
86 OwnValidation::IsGlobalAddressReservation => true,
87 OwnValidation::IsTypedObject(_, _) => true,
88 };
89 if !is_valid {
90 return Err(PayloadValidationError::ValidationError(
91 ValidationError::CustomError(format!(
92 "Expected = Own<{:?}>, found node id with entity type: {:?}",
93 own_validation,
94 node_id.entity_type()
95 )),
96 ));
97 }
98 }
99 };
100 Ok(())
101}