radix_common/data/
conversions.rs

1use crate::prelude::*;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub enum ConversionError {
5    NoDirectEquivalence,
6    DecodeError(DecodeError),
7    EncodeError(EncodeError),
8}
9
10type Result<T> = core::result::Result<T, ConversionError>;
11
12pub fn scrypto_value_to_manifest_value(scrypto_value: ScryptoValue) -> Result<ManifestValue> {
13    match scrypto_value {
14        ScryptoValue::Bool { value } => Ok(ManifestValue::Bool { value }),
15        ScryptoValue::I8 { value } => Ok(ManifestValue::I8 { value }),
16        ScryptoValue::I16 { value } => Ok(ManifestValue::I16 { value }),
17        ScryptoValue::I32 { value } => Ok(ManifestValue::I32 { value }),
18        ScryptoValue::I64 { value } => Ok(ManifestValue::I64 { value }),
19        ScryptoValue::I128 { value } => Ok(ManifestValue::I128 { value }),
20        ScryptoValue::U8 { value } => Ok(ManifestValue::U8 { value }),
21        ScryptoValue::U16 { value } => Ok(ManifestValue::U16 { value }),
22        ScryptoValue::U32 { value } => Ok(ManifestValue::U32 { value }),
23        ScryptoValue::U64 { value } => Ok(ManifestValue::U64 { value }),
24        ScryptoValue::U128 { value } => Ok(ManifestValue::U128 { value }),
25        ScryptoValue::String { value } => Ok(ManifestValue::String { value }),
26        ScryptoValue::Enum {
27            discriminator,
28            fields,
29        } => fields
30            .into_iter()
31            .map(scrypto_value_to_manifest_value)
32            .collect::<Result<_>>()
33            .map(|fields| ManifestValue::Enum {
34                discriminator,
35                fields,
36            }),
37        ScryptoValue::Array {
38            element_value_kind,
39            elements,
40        } => {
41            let element_value_kind = scrypto_value_kind_to_manifest_value_kind(element_value_kind)?;
42            let elements = elements
43                .into_iter()
44                .map(scrypto_value_to_manifest_value)
45                .collect::<Result<Vec<_>>>()?;
46            Ok(ManifestValue::Array {
47                element_value_kind,
48                elements,
49            })
50        }
51        ScryptoValue::Tuple { fields } => fields
52            .into_iter()
53            .map(scrypto_value_to_manifest_value)
54            .collect::<Result<_>>()
55            .map(|fields| ManifestValue::Tuple { fields }),
56        ScryptoValue::Map {
57            key_value_kind,
58            value_value_kind,
59            entries,
60        } => {
61            let key_value_kind = scrypto_value_kind_to_manifest_value_kind(key_value_kind)?;
62            let value_value_kind = scrypto_value_kind_to_manifest_value_kind(value_value_kind)?;
63            let entries = entries
64                .into_iter()
65                .map(|(key, value)| -> Result<(ManifestValue, ManifestValue)> {
66                    let key = scrypto_value_to_manifest_value(key)?;
67                    let value = scrypto_value_to_manifest_value(value)?;
68                    Ok((key, value))
69                })
70                .collect::<Result<Vec<_>>>()?;
71            Ok(ManifestValue::Map {
72                key_value_kind,
73                value_value_kind,
74                entries,
75            })
76        }
77        ScryptoValue::Custom {
78            value: ScryptoCustomValue::Decimal(value),
79        } => Ok(ManifestValue::Custom {
80            value: ManifestCustomValue::Decimal(from_decimal(&value)),
81        }),
82        ScryptoValue::Custom {
83            value: ScryptoCustomValue::PreciseDecimal(value),
84        } => Ok(ManifestValue::Custom {
85            value: ManifestCustomValue::PreciseDecimal(from_precise_decimal(&value)),
86        }),
87        ScryptoValue::Custom {
88            value: ScryptoCustomValue::Reference(value),
89        } => Ok(ManifestValue::Custom {
90            value: ManifestCustomValue::Address(ManifestAddress::Static(value.0)),
91        }),
92        ScryptoValue::Custom {
93            value: ScryptoCustomValue::NonFungibleLocalId(value),
94        } => Ok(ManifestValue::Custom {
95            value: ManifestCustomValue::NonFungibleLocalId(from_non_fungible_local_id(value)),
96        }),
97        ScryptoValue::Custom {
98            value: ScryptoCustomValue::Own(..),
99        } => Err(ConversionError::NoDirectEquivalence),
100    }
101}
102
103pub fn scrypto_value_kind_to_manifest_value_kind(
104    value_kind: ScryptoValueKind,
105) -> Result<ManifestValueKind> {
106    match value_kind {
107        ScryptoValueKind::Bool => Ok(ManifestValueKind::Bool),
108        ScryptoValueKind::I8 => Ok(ManifestValueKind::I8),
109        ScryptoValueKind::I16 => Ok(ManifestValueKind::I16),
110        ScryptoValueKind::I32 => Ok(ManifestValueKind::I32),
111        ScryptoValueKind::I64 => Ok(ManifestValueKind::I64),
112        ScryptoValueKind::I128 => Ok(ManifestValueKind::I128),
113        ScryptoValueKind::U8 => Ok(ManifestValueKind::U8),
114        ScryptoValueKind::U16 => Ok(ManifestValueKind::U16),
115        ScryptoValueKind::U32 => Ok(ManifestValueKind::U32),
116        ScryptoValueKind::U64 => Ok(ManifestValueKind::U64),
117        ScryptoValueKind::U128 => Ok(ManifestValueKind::U128),
118        ScryptoValueKind::String => Ok(ManifestValueKind::String),
119        ScryptoValueKind::Enum => Ok(ManifestValueKind::Enum),
120        ScryptoValueKind::Array => Ok(ManifestValueKind::Array),
121        ScryptoValueKind::Tuple => Ok(ManifestValueKind::Tuple),
122        ScryptoValueKind::Map => Ok(ManifestValueKind::Map),
123        ScryptoValueKind::Custom(ScryptoCustomValueKind::Reference) => {
124            Ok(ManifestValueKind::Custom(ManifestCustomValueKind::Address))
125        }
126        ScryptoValueKind::Custom(ScryptoCustomValueKind::Own) => {
127            Err(ConversionError::NoDirectEquivalence)
128        }
129        ScryptoValueKind::Custom(ScryptoCustomValueKind::Decimal) => {
130            Ok(ManifestValueKind::Custom(ManifestCustomValueKind::Decimal))
131        }
132        ScryptoValueKind::Custom(ScryptoCustomValueKind::PreciseDecimal) => Ok(
133            ManifestValueKind::Custom(ManifestCustomValueKind::PreciseDecimal),
134        ),
135        ScryptoValueKind::Custom(ScryptoCustomValueKind::NonFungibleLocalId) => Ok(
136            ManifestValueKind::Custom(ManifestCustomValueKind::NonFungibleLocalId),
137        ),
138    }
139}
140
141pub fn manifest_value_to_scrypto_value(manifest_value: ManifestValue) -> Result<ScryptoValue> {
142    match manifest_value {
143        ManifestValue::Bool { value } => Ok(ScryptoValue::Bool { value }),
144        ManifestValue::I8 { value } => Ok(ScryptoValue::I8 { value }),
145        ManifestValue::I16 { value } => Ok(ScryptoValue::I16 { value }),
146        ManifestValue::I32 { value } => Ok(ScryptoValue::I32 { value }),
147        ManifestValue::I64 { value } => Ok(ScryptoValue::I64 { value }),
148        ManifestValue::I128 { value } => Ok(ScryptoValue::I128 { value }),
149        ManifestValue::U8 { value } => Ok(ScryptoValue::U8 { value }),
150        ManifestValue::U16 { value } => Ok(ScryptoValue::U16 { value }),
151        ManifestValue::U32 { value } => Ok(ScryptoValue::U32 { value }),
152        ManifestValue::U64 { value } => Ok(ScryptoValue::U64 { value }),
153        ManifestValue::U128 { value } => Ok(ScryptoValue::U128 { value }),
154        ManifestValue::String { value } => Ok(ScryptoValue::String { value }),
155        ManifestValue::Enum {
156            discriminator,
157            fields,
158        } => fields
159            .into_iter()
160            .map(manifest_value_to_scrypto_value)
161            .collect::<Result<_>>()
162            .map(|fields| ScryptoValue::Enum {
163                discriminator,
164                fields,
165            }),
166        ManifestValue::Array {
167            element_value_kind,
168            elements,
169        } => {
170            let element_value_kind = manifest_value_kind_to_scrypto_value_kind(element_value_kind)?;
171            let elements = elements
172                .into_iter()
173                .map(manifest_value_to_scrypto_value)
174                .collect::<Result<Vec<_>>>()?;
175            Ok(ScryptoValue::Array {
176                element_value_kind,
177                elements,
178            })
179        }
180        ManifestValue::Tuple { fields } => fields
181            .into_iter()
182            .map(manifest_value_to_scrypto_value)
183            .collect::<Result<_>>()
184            .map(|fields| ScryptoValue::Tuple { fields }),
185        ManifestValue::Map {
186            key_value_kind,
187            value_value_kind,
188            entries,
189        } => {
190            let key_value_kind = manifest_value_kind_to_scrypto_value_kind(key_value_kind)?;
191            let value_value_kind = manifest_value_kind_to_scrypto_value_kind(value_value_kind)?;
192            let entries = entries
193                .into_iter()
194                .map(|(key, value)| -> Result<(ScryptoValue, ScryptoValue)> {
195                    let key = manifest_value_to_scrypto_value(key)?;
196                    let value = manifest_value_to_scrypto_value(value)?;
197                    Ok((key, value))
198                })
199                .collect::<Result<Vec<_>>>()?;
200            Ok(ScryptoValue::Map {
201                key_value_kind,
202                value_value_kind,
203                entries,
204            })
205        }
206        ManifestValue::Custom {
207            value: ManifestCustomValue::Address(ManifestAddress::Static(value)),
208        } => Ok(ScryptoValue::Custom {
209            value: ScryptoCustomValue::Reference(Reference(value)),
210        }),
211        ManifestValue::Custom {
212            value: ManifestCustomValue::Decimal(value),
213        } => Ok(ScryptoValue::Custom {
214            value: ScryptoCustomValue::Decimal(to_decimal(&value)),
215        }),
216        ManifestValue::Custom {
217            value: ManifestCustomValue::PreciseDecimal(value),
218        } => Ok(ScryptoValue::Custom {
219            value: ScryptoCustomValue::PreciseDecimal(to_precise_decimal(&value)),
220        }),
221        ManifestValue::Custom {
222            value: ManifestCustomValue::NonFungibleLocalId(value),
223        } => Ok(ScryptoValue::Custom {
224            value: ScryptoCustomValue::NonFungibleLocalId(to_non_fungible_local_id(value)),
225        }),
226        ManifestValue::Custom {
227            value:
228                ManifestCustomValue::Bucket(..)
229                | ManifestCustomValue::Proof(..)
230                | ManifestCustomValue::AddressReservation(..)
231                | ManifestCustomValue::Expression(..)
232                | ManifestCustomValue::Blob(..)
233                | ManifestCustomValue::Address(ManifestAddress::Named(..)),
234        } => Err(ConversionError::NoDirectEquivalence),
235    }
236}
237
238pub fn manifest_value_kind_to_scrypto_value_kind(
239    value_kind: ManifestValueKind,
240) -> Result<ScryptoValueKind> {
241    match value_kind {
242        ManifestValueKind::Bool => Ok(ScryptoValueKind::Bool),
243        ManifestValueKind::I8 => Ok(ScryptoValueKind::I8),
244        ManifestValueKind::I16 => Ok(ScryptoValueKind::I16),
245        ManifestValueKind::I32 => Ok(ScryptoValueKind::I32),
246        ManifestValueKind::I64 => Ok(ScryptoValueKind::I64),
247        ManifestValueKind::I128 => Ok(ScryptoValueKind::I128),
248        ManifestValueKind::U8 => Ok(ScryptoValueKind::U8),
249        ManifestValueKind::U16 => Ok(ScryptoValueKind::U16),
250        ManifestValueKind::U32 => Ok(ScryptoValueKind::U32),
251        ManifestValueKind::U64 => Ok(ScryptoValueKind::U64),
252        ManifestValueKind::U128 => Ok(ScryptoValueKind::U128),
253        ManifestValueKind::String => Ok(ScryptoValueKind::String),
254        ManifestValueKind::Enum => Ok(ScryptoValueKind::Enum),
255        ManifestValueKind::Array => Ok(ScryptoValueKind::Array),
256        ManifestValueKind::Tuple => Ok(ScryptoValueKind::Tuple),
257        ManifestValueKind::Map => Ok(ScryptoValueKind::Map),
258        ManifestValueKind::Custom(ManifestCustomValueKind::Address) => {
259            Ok(ScryptoValueKind::Custom(ScryptoCustomValueKind::Reference))
260        }
261        ManifestValueKind::Custom(ManifestCustomValueKind::Decimal) => {
262            Ok(ScryptoValueKind::Custom(ScryptoCustomValueKind::Decimal))
263        }
264        ManifestValueKind::Custom(ManifestCustomValueKind::PreciseDecimal) => Ok(
265            ScryptoValueKind::Custom(ScryptoCustomValueKind::PreciseDecimal),
266        ),
267        ManifestValueKind::Custom(ManifestCustomValueKind::NonFungibleLocalId) => Ok(
268            ScryptoValueKind::Custom(ScryptoCustomValueKind::NonFungibleLocalId),
269        ),
270        ManifestValueKind::Custom(
271            ManifestCustomValueKind::Bucket
272            | ManifestCustomValueKind::Proof
273            | ManifestCustomValueKind::AddressReservation
274            | ManifestCustomValueKind::Expression
275            | ManifestCustomValueKind::Blob,
276        ) => Err(ConversionError::NoDirectEquivalence),
277    }
278}