radix_common/data/manifest/
definitions.rs1use vec_traits::vec_decode_with_nice_error;
2
3use crate::internal_prelude::*;
4
5pub use crate::constants::MANIFEST_SBOR_V1_MAX_DEPTH;
6pub use crate::constants::MANIFEST_SBOR_V1_PAYLOAD_PREFIX;
7
8pub type ManifestEncoder<'a> = VecEncoder<'a, ManifestCustomValueKind>;
9pub type ManifestDecoder<'a> = VecDecoder<'a, ManifestCustomValueKind>;
10pub type ManifestValueKind = ValueKind<ManifestCustomValueKind>;
11pub type ManifestValue = Value<ManifestCustomValueKind, ManifestCustomValue>;
12pub type ManifestEnumVariantValue = EnumVariantValue<ManifestCustomValueKind, ManifestCustomValue>;
13pub type ManifestTraverser<'a> = VecTraverser<'a, ManifestCustomTraversal>;
14
15pub trait ManifestCategorize: Categorize<ManifestCustomValueKind> {}
16impl<T: Categorize<ManifestCustomValueKind> + ?Sized> ManifestCategorize for T {}
17
18pub trait ManifestSborEnum: SborEnum<ManifestCustomValueKind> {}
19impl<T: SborEnum<ManifestCustomValueKind> + ?Sized> ManifestSborEnum for T {}
20
21pub trait ManifestSborEnumVariantFor<E: ManifestSborEnum>:
22 SborEnumVariantFor<E, ManifestCustomValueKind>
23{
24}
25impl<E: ManifestSborEnum, T: SborEnumVariantFor<E, ManifestCustomValueKind> + ?Sized>
26 ManifestSborEnumVariantFor<E> for T
27{
28}
29
30pub trait ManifestSborTuple: SborTuple<ManifestCustomValueKind> {}
31impl<T: SborTuple<ManifestCustomValueKind> + ?Sized> ManifestSborTuple for T {}
32
33pub trait ManifestDecode: for<'a> Decode<ManifestCustomValueKind, ManifestDecoder<'a>> {}
34impl<T: for<'a> Decode<ManifestCustomValueKind, ManifestDecoder<'a>>> ManifestDecode for T {}
35
36pub trait ManifestEncode: for<'a> Encode<ManifestCustomValueKind, ManifestEncoder<'a>> {}
37impl<T: for<'a> Encode<ManifestCustomValueKind, ManifestEncoder<'a>> + ?Sized> ManifestEncode
38 for T
39{
40}
41
42pub struct ManifestArgs(crate::data::manifest::ManifestValue, usize);
43
44impl ManifestArgs {
45 pub fn new_from_tuple_or_panic(value: ManifestValue) -> Self {
46 let length = match &value {
47 Value::Tuple { fields } => fields.len(),
48 _ => {
49 panic!("ManifestArgs has to be a Tuple");
50 }
51 };
52 Self(value, length)
53 }
54}
55
56impl Categorize<ManifestCustomValueKind> for ManifestArgs {
57 #[inline]
58 fn value_kind() -> ValueKind<ManifestCustomValueKind> {
59 ValueKind::Tuple
60 }
61}
62
63impl SborTuple<ManifestCustomValueKind> for ManifestArgs {
64 fn get_length(&self) -> usize {
65 self.1
66 }
67}
68
69impl<'a> Encode<ManifestCustomValueKind, ManifestEncoder<'a>> for ManifestArgs {
70 #[inline]
71 fn encode_value_kind(&self, encoder: &mut ManifestEncoder<'a>) -> Result<(), EncodeError> {
72 self.0.encode_value_kind(encoder)
73 }
74
75 #[inline]
76 fn encode_body(&self, encoder: &mut ManifestEncoder<'a>) -> Result<(), EncodeError> {
77 self.0.encode_body(encoder)
78 }
79}
80
81impl From<ManifestArgs> for ManifestValue {
82 fn from(value: ManifestArgs) -> Self {
83 value.0
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq)]
88pub enum RustToManifestValueError {
89 DecodeError(DecodeError),
90 EncodeError(EncodeError),
91}
92
93#[derive(Debug, Clone, PartialEq, Eq)]
94pub enum ManifestToRustValueError {
95 DecodeError(DecodeError),
96 EncodeError(EncodeError),
97}
98
99pub fn manifest_encode<T: ManifestEncode + ?Sized>(value: &T) -> Result<Vec<u8>, EncodeError> {
100 manifest_encode_with_depth_limit(value, MANIFEST_SBOR_V1_MAX_DEPTH)
101}
102
103pub fn manifest_encode_with_depth_limit<T: ManifestEncode + ?Sized>(
104 value: &T,
105 depth_limit: usize,
106) -> Result<Vec<u8>, EncodeError> {
107 let mut buf = Vec::with_capacity(512);
108 let encoder = ManifestEncoder::new(&mut buf, depth_limit);
109 encoder.encode_payload(value, MANIFEST_SBOR_V1_PAYLOAD_PREFIX)?;
110 Ok(buf)
111}
112
113pub fn manifest_decode<T: ManifestDecode>(buf: &[u8]) -> Result<T, DecodeError> {
114 manifest_decode_with_depth_limit(buf, MANIFEST_SBOR_V1_MAX_DEPTH)
115}
116
117pub fn manifest_decode_with_depth_limit<T: ManifestDecode>(
118 buf: &[u8],
119 depth_limit: usize,
120) -> Result<T, DecodeError> {
121 ManifestDecoder::new(buf, depth_limit).decode_payload(MANIFEST_SBOR_V1_PAYLOAD_PREFIX)
122}
123
124pub fn manifest_decode_with_nice_error<T: ManifestDecode + ScryptoDescribe>(
133 buf: &[u8],
134) -> Result<T, String> {
135 vec_decode_with_nice_error::<ManifestCustomExtension, T>(buf, MANIFEST_SBOR_V1_MAX_DEPTH)
136}
137
138pub fn manifest_decode_with_depth_limit_and_nice_error<T: ManifestDecode + ScryptoDescribe>(
147 buf: &[u8],
148 depth_limit: usize,
149) -> Result<T, String> {
150 vec_decode_with_nice_error::<ManifestCustomExtension, T>(buf, depth_limit)
151}
152
153pub fn to_manifest_value<T: ManifestEncode + ?Sized>(
154 value: &T,
155) -> Result<ManifestValue, RustToManifestValueError> {
156 let encoded = manifest_encode(value).map_err(RustToManifestValueError::EncodeError)?;
157
158 manifest_decode(&encoded).map_err(RustToManifestValueError::DecodeError)
159}
160
161pub fn from_manifest_value<T: ManifestDecode>(
162 manifest_value: &ManifestValue,
163) -> Result<T, ManifestToRustValueError> {
164 let encoded = manifest_encode(manifest_value).map_err(ManifestToRustValueError::EncodeError)?;
165
166 manifest_decode(&encoded).map_err(ManifestToRustValueError::DecodeError)
167}
168
169#[cfg(test)]
170mod tests {
171 use super::*;
172
173 #[test]
174 fn test_manifest_value_conversions() {
175 let invalid_value = ManifestValue::Tuple {
176 fields: vec![ManifestValue::Array {
177 element_value_kind: ValueKind::U8,
178 elements: vec![
179 ManifestValue::U8 { value: 1 },
180 ManifestValue::U16 { value: 2 },
181 ],
182 }],
183 };
184 assert_matches!(
185 to_manifest_value(&invalid_value),
186 Err(RustToManifestValueError::EncodeError(
187 EncodeError::MismatchingArrayElementValueKind { .. }
188 ))
189 );
190
191 let invalid_value = ManifestValue::Map {
192 key_value_kind: ValueKind::U8,
193 value_value_kind: ValueKind::I8,
194 entries: vec![(
195 ManifestValue::U16 { value: 1 },
196 ManifestValue::I8 { value: 1 },
197 )],
198 };
199 assert_matches!(
200 to_manifest_value(&invalid_value),
201 Err(RustToManifestValueError::EncodeError(
202 EncodeError::MismatchingMapKeyValueKind { .. }
203 ))
204 );
205
206 let invalid_value = ManifestValue::Map {
207 key_value_kind: ValueKind::U8,
208 value_value_kind: ValueKind::I8,
209 entries: vec![(
210 ManifestValue::U8 { value: 1 },
211 ManifestValue::I16 { value: 1 },
212 )],
213 };
214 assert_matches!(
215 to_manifest_value(&invalid_value),
216 Err(RustToManifestValueError::EncodeError(
217 EncodeError::MismatchingMapValueValueKind { .. }
218 ))
219 );
220
221 let too_deep_tuple = get_tuple_of_depth(MANIFEST_SBOR_V1_MAX_DEPTH + 1).unwrap();
222 assert_matches!(
223 to_manifest_value(&too_deep_tuple),
224 Err(RustToManifestValueError::EncodeError(
225 EncodeError::MaxDepthExceeded { .. }
226 ))
227 );
228
229 let fine_tuple = get_tuple_of_depth(MANIFEST_SBOR_V1_MAX_DEPTH).unwrap();
230 assert!(to_manifest_value(&fine_tuple).is_ok());
231 }
232
233 pub fn get_tuple_of_depth(depth: usize) -> Option<ManifestValue> {
234 if depth <= 1 {
236 None
237 } else if depth <= 2 {
238 Some(ManifestValue::Tuple {
239 fields: vec![ManifestValue::U8 { value: 1 }],
240 })
241 } else {
242 let value = get_tuple_of_depth(depth - 1).unwrap();
243 Some(ManifestValue::Tuple {
244 fields: vec![value],
245 })
246 }
247 }
248}