Skip to main content

radix_transactions/data/
transformer.rs

1use crate::data::{to_decimal, to_non_fungible_local_id, to_precise_decimal};
2use crate::internal_prelude::*;
3use radix_common::data::manifest::model::{
4    ManifestBlobRef, ManifestBucket, ManifestExpression, ManifestProof,
5};
6use radix_common::data::manifest::{
7    ManifestCustomValue, ManifestCustomValueKind, ManifestValue, ManifestValueKind,
8};
9use radix_common::data::scrypto::model::{Own, Reference};
10use radix_common::data::scrypto::{
11    ScryptoCustomValue, ScryptoCustomValueKind, ScryptoValue, ScryptoValueKind,
12};
13use sbor::rust::vec::Vec;
14
15pub trait TransformHandler<E> {
16    fn replace_bucket(&mut self, b: ManifestBucket) -> Result<Own, E>;
17    fn replace_proof(&mut self, p: ManifestProof) -> Result<Own, E>;
18    fn replace_address_reservation(&mut self, p: ManifestAddressReservation) -> Result<Own, E>;
19    fn replace_named_address(&mut self, p: ManifestNamedAddress) -> Result<Reference, E>;
20    fn replace_expression(&mut self, e: ManifestExpression) -> Result<Vec<Own>, E>;
21    fn replace_blob(&mut self, b: ManifestBlobRef) -> Result<Vec<u8>, E>;
22}
23
24pub fn transform<T: TransformHandler<E>, E>(
25    value: ManifestValue,
26    handler: &mut T,
27) -> Result<ScryptoValue, E> {
28    match value {
29        sbor::Value::Bool { value } => Ok(ScryptoValue::Bool { value }),
30        sbor::Value::I8 { value } => Ok(ScryptoValue::I8 { value }),
31        sbor::Value::I16 { value } => Ok(ScryptoValue::I16 { value }),
32        sbor::Value::I32 { value } => Ok(ScryptoValue::I32 { value }),
33        sbor::Value::I64 { value } => Ok(ScryptoValue::I64 { value }),
34        sbor::Value::I128 { value } => Ok(ScryptoValue::I128 { value }),
35        sbor::Value::U8 { value } => Ok(ScryptoValue::U8 { value }),
36        sbor::Value::U16 { value } => Ok(ScryptoValue::U16 { value }),
37        sbor::Value::U32 { value } => Ok(ScryptoValue::U32 { value }),
38        sbor::Value::U64 { value } => Ok(ScryptoValue::U64 { value }),
39        sbor::Value::U128 { value } => Ok(ScryptoValue::U128 { value }),
40        sbor::Value::String { value } => Ok(ScryptoValue::String { value }),
41        sbor::Value::Enum {
42            discriminator,
43            fields,
44        } => {
45            let mut transformed_fields = Vec::new();
46            for field in fields {
47                transformed_fields.push(transform(field, handler)?);
48            }
49            Ok(ScryptoValue::Enum {
50                discriminator,
51                fields: transformed_fields,
52            })
53        }
54        sbor::Value::Array {
55            element_value_kind,
56            elements,
57        } => {
58            let mut transformed_elements = Vec::new();
59            for element in elements {
60                transformed_elements.push(transform(element, handler)?);
61            }
62            Ok(ScryptoValue::Array {
63                element_value_kind: transform_value_kind(element_value_kind),
64                elements: transformed_elements,
65            })
66        }
67        sbor::Value::Tuple { fields } => {
68            let mut transformed_fields = Vec::new();
69            for field in fields {
70                transformed_fields.push(transform(field, handler)?);
71            }
72            Ok(ScryptoValue::Tuple {
73                fields: transformed_fields,
74            })
75        }
76        sbor::Value::Map {
77            key_value_kind,
78            value_value_kind,
79            entries,
80        } => {
81            let mut transformed_entries = Vec::new();
82            for entry in entries {
83                transformed_entries
84                    .push((transform(entry.0, handler)?, transform(entry.1, handler)?));
85            }
86            Ok(ScryptoValue::Map {
87                key_value_kind: transform_value_kind(key_value_kind),
88                value_value_kind: transform_value_kind(value_value_kind),
89                entries: transformed_entries,
90            })
91        }
92        sbor::Value::Custom { value } => match value {
93            ManifestCustomValue::Address(address) => match address {
94                ManifestAddress::Static(node_id) => Ok(ScryptoValue::Custom {
95                    value: ScryptoCustomValue::Reference(Reference(node_id)),
96                }),
97                ManifestAddress::Named(name_id) => Ok(ScryptoValue::Custom {
98                    value: ScryptoCustomValue::Reference(handler.replace_named_address(name_id)?),
99                }),
100            },
101            ManifestCustomValue::Bucket(b) => Ok(ScryptoValue::Custom {
102                value: ScryptoCustomValue::Own(handler.replace_bucket(b)?),
103            }),
104            ManifestCustomValue::Proof(p) => Ok(ScryptoValue::Custom {
105                value: ScryptoCustomValue::Own(handler.replace_proof(p)?),
106            }),
107            ManifestCustomValue::AddressReservation(p) => Ok(ScryptoValue::Custom {
108                value: ScryptoCustomValue::Own(handler.replace_address_reservation(p)?),
109            }),
110            ManifestCustomValue::Expression(e) => Ok(ScryptoValue::Array {
111                element_value_kind: ScryptoValueKind::Custom(ScryptoCustomValueKind::Own),
112                elements: handler
113                    .replace_expression(e)?
114                    .into_iter()
115                    .map(|e| ScryptoValue::Custom {
116                        value: ScryptoCustomValue::Own(e),
117                    })
118                    .collect(),
119            }),
120            ManifestCustomValue::Blob(b) => Ok(ScryptoValue::Array {
121                element_value_kind: ScryptoValueKind::U8,
122                elements: handler
123                    .replace_blob(b)?
124                    .into_iter()
125                    .map(|e| ScryptoValue::U8 { value: e })
126                    .collect(),
127            }),
128            ManifestCustomValue::Decimal(d) => Ok(ScryptoValue::Custom {
129                value: ScryptoCustomValue::Decimal(to_decimal(d)),
130            }),
131            ManifestCustomValue::PreciseDecimal(d) => Ok(ScryptoValue::Custom {
132                value: ScryptoCustomValue::PreciseDecimal(to_precise_decimal(d)),
133            }),
134            ManifestCustomValue::NonFungibleLocalId(id) => Ok(ScryptoValue::Custom {
135                value: ScryptoCustomValue::NonFungibleLocalId(to_non_fungible_local_id(id)),
136            }),
137        },
138    }
139}
140
141pub fn transform_value_kind(kind: ManifestValueKind) -> ScryptoValueKind {
142    match kind {
143        sbor::ValueKind::Bool => ScryptoValueKind::Bool,
144        sbor::ValueKind::I8 => ScryptoValueKind::I8,
145        sbor::ValueKind::I16 => ScryptoValueKind::I16,
146        sbor::ValueKind::I32 => ScryptoValueKind::I32,
147        sbor::ValueKind::I64 => ScryptoValueKind::I64,
148        sbor::ValueKind::I128 => ScryptoValueKind::I128,
149        sbor::ValueKind::U8 => ScryptoValueKind::U8,
150        sbor::ValueKind::U16 => ScryptoValueKind::U16,
151        sbor::ValueKind::U32 => ScryptoValueKind::U32,
152        sbor::ValueKind::U64 => ScryptoValueKind::U64,
153        sbor::ValueKind::U128 => ScryptoValueKind::U128,
154        sbor::ValueKind::String => ScryptoValueKind::String,
155        sbor::ValueKind::Enum => ScryptoValueKind::Enum,
156        sbor::ValueKind::Array => ScryptoValueKind::Array,
157        sbor::ValueKind::Tuple => ScryptoValueKind::Tuple,
158        sbor::ValueKind::Map => ScryptoValueKind::Map,
159        sbor::ValueKind::Custom(c) => match c {
160            ManifestCustomValueKind::Address => {
161                ScryptoValueKind::Custom(ScryptoCustomValueKind::Reference)
162            }
163            ManifestCustomValueKind::Bucket => {
164                ScryptoValueKind::Custom(ScryptoCustomValueKind::Own)
165            }
166            ManifestCustomValueKind::Proof => ScryptoValueKind::Custom(ScryptoCustomValueKind::Own),
167            ManifestCustomValueKind::Expression => ScryptoValueKind::Array,
168            ManifestCustomValueKind::Blob => ScryptoValueKind::Array,
169            ManifestCustomValueKind::Decimal => {
170                ScryptoValueKind::Custom(ScryptoCustomValueKind::Decimal)
171            }
172            ManifestCustomValueKind::PreciseDecimal => {
173                ScryptoValueKind::Custom(ScryptoCustomValueKind::PreciseDecimal)
174            }
175            ManifestCustomValueKind::NonFungibleLocalId => {
176                ScryptoValueKind::Custom(ScryptoCustomValueKind::NonFungibleLocalId)
177            }
178            ManifestCustomValueKind::AddressReservation => {
179                ScryptoValueKind::Custom(ScryptoCustomValueKind::Own)
180            }
181        },
182    }
183}