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}