radix_common/data/manifest/model/
manifest_expression.rs1use crate::internal_prelude::*;
2
3use crate::data::manifest::*;
4use crate::*;
5
6#[cfg_attr(
7 feature = "fuzzing",
8 derive(::arbitrary::Arbitrary, ::serde::Serialize, ::serde::Deserialize)
9)]
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11pub enum ManifestExpression {
12 EntireWorktop,
14 EntireAuthZone,
16}
17
18#[cfg_attr(feature = "fuzzing", derive(::arbitrary::Arbitrary))]
23#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24pub enum ManifestBucketBatch {
25 ManifestBuckets(Vec<ManifestBucket>),
26 EntireWorktop,
27}
28
29labelled_resolvable_with_identity_impl!(ManifestBucketBatch, resolver_output: ManifestBucket);
30
31impl<T: LabelledResolve<Vec<ManifestBucket>>> LabelledResolveFrom<T> for ManifestBucketBatch {
32 fn labelled_resolve_from(
33 value: T,
34 resolver: &impl LabelResolver<ManifestBucket>,
35 ) -> ManifestBucketBatch {
36 ManifestBucketBatch::ManifestBuckets(value.labelled_resolve(resolver))
37 }
38}
39
40impl LabelledResolveFrom<ManifestExpression> for ManifestBucketBatch {
41 fn labelled_resolve_from(
42 value: ManifestExpression,
43 _: &impl LabelResolver<ManifestBucket>,
44 ) -> ManifestBucketBatch {
45 match value {
46 ManifestExpression::EntireWorktop => {
47 ManifestBucketBatch::EntireWorktop
50 }
51 ManifestExpression::EntireAuthZone => {
52 panic!("Not an allowed expression for a batch of buckets")
53 }
54 }
55 }
56}
57
58impl ManifestBucketBatch {
59 pub fn from_buckets(buckets: impl IntoIterator<Item = ManifestBucket>) -> Self {
60 Self::ManifestBuckets(buckets.into_iter().collect())
61 }
62}
63
64impl<E: sbor::Encoder<ManifestCustomValueKind>> sbor::Encode<ManifestCustomValueKind, E>
65 for ManifestBucketBatch
66{
67 #[inline]
68 fn encode_value_kind(&self, encoder: &mut E) -> Result<(), sbor::EncodeError> {
69 match self {
70 ManifestBucketBatch::ManifestBuckets(buckets) => buckets.encode_value_kind(encoder),
71 ManifestBucketBatch::EntireWorktop => {
72 ManifestExpression::EntireWorktop.encode_value_kind(encoder)
73 }
74 }
75 }
76
77 #[inline]
78 fn encode_body(&self, encoder: &mut E) -> Result<(), sbor::EncodeError> {
79 match self {
80 ManifestBucketBatch::ManifestBuckets(buckets) => buckets.encode_body(encoder),
81 ManifestBucketBatch::EntireWorktop => {
82 ManifestExpression::EntireWorktop.encode_body(encoder)
83 }
84 }
85 }
86}
87
88impl<D: sbor::Decoder<ManifestCustomValueKind>> sbor::Decode<ManifestCustomValueKind, D>
89 for ManifestBucketBatch
90{
91 fn decode_body_with_value_kind(
92 decoder: &mut D,
93 value_kind: sbor::ValueKind<ManifestCustomValueKind>,
94 ) -> Result<Self, sbor::DecodeError> {
95 Ok(match value_kind {
96 ValueKind::Array => Self::ManifestBuckets(
97 Vec::<ManifestBucket>::decode_body_with_value_kind(decoder, value_kind)?,
98 ),
99 ValueKind::Custom(_) => {
100 let expression =
101 ManifestExpression::decode_body_with_value_kind(decoder, value_kind)?;
102 if !matches!(expression, ManifestExpression::EntireWorktop) {
103 return Err(sbor::DecodeError::InvalidCustomValue);
104 }
105 Self::EntireWorktop
106 }
107 _ => {
108 return Err(sbor::DecodeError::UnexpectedValueKind {
109 expected: ManifestValueKind::Array.as_u8(),
110 actual: value_kind.as_u8(),
111 });
112 }
113 })
114 }
115}
116
117impl sbor::Describe<ScryptoCustomTypeKind> for ManifestBucketBatch {
118 const TYPE_ID: sbor::RustTypeId = Vec::<ManifestBucket>::TYPE_ID;
119
120 fn type_data() -> sbor::TypeData<ScryptoCustomTypeKind, sbor::RustTypeId> {
121 Vec::<ManifestBucket>::type_data()
122 }
123}
124
125#[cfg_attr(feature = "fuzzing", derive(::arbitrary::Arbitrary))]
126#[derive(Debug, Clone, PartialEq, Eq, Hash)]
127pub enum ManifestProofBatch {
128 ManifestProofs(Vec<ManifestProof>),
129 EntireAuthZone,
130}
131
132labelled_resolvable_with_identity_impl!(ManifestProofBatch, resolver_output: ManifestProof);
133
134impl<T: LabelledResolve<Vec<ManifestProof>>> LabelledResolveFrom<T> for ManifestProofBatch {
135 fn labelled_resolve_from(
136 value: T,
137 resolver: &impl LabelResolver<ManifestProof>,
138 ) -> ManifestProofBatch {
139 ManifestProofBatch::ManifestProofs(value.labelled_resolve(resolver))
140 }
141}
142
143impl LabelledResolveFrom<ManifestExpression> for ManifestProofBatch {
144 fn labelled_resolve_from(
145 value: ManifestExpression,
146 _: &impl LabelResolver<ManifestProof>,
147 ) -> ManifestProofBatch {
148 match value {
149 ManifestExpression::EntireWorktop => {
150 panic!("Not an allowed expression for a batch of proofs");
151 }
152 ManifestExpression::EntireAuthZone => ManifestProofBatch::EntireAuthZone,
153 }
154 }
155}
156
157impl<E: sbor::Encoder<ManifestCustomValueKind>> sbor::Encode<ManifestCustomValueKind, E>
158 for ManifestProofBatch
159{
160 #[inline]
161 fn encode_value_kind(&self, encoder: &mut E) -> Result<(), sbor::EncodeError> {
162 match self {
163 ManifestProofBatch::ManifestProofs(proofs) => proofs.encode_value_kind(encoder),
164 ManifestProofBatch::EntireAuthZone => {
165 ManifestExpression::EntireAuthZone.encode_value_kind(encoder)
166 }
167 }
168 }
169
170 #[inline]
171 fn encode_body(&self, encoder: &mut E) -> Result<(), sbor::EncodeError> {
172 match self {
173 ManifestProofBatch::ManifestProofs(proofs) => proofs.encode_body(encoder),
174 ManifestProofBatch::EntireAuthZone => {
175 ManifestExpression::EntireAuthZone.encode_body(encoder)
176 }
177 }
178 }
179}
180
181impl<D: sbor::Decoder<ManifestCustomValueKind>> sbor::Decode<ManifestCustomValueKind, D>
182 for ManifestProofBatch
183{
184 fn decode_body_with_value_kind(
185 decoder: &mut D,
186 value_kind: sbor::ValueKind<ManifestCustomValueKind>,
187 ) -> Result<Self, sbor::DecodeError> {
188 Ok(match value_kind {
189 ValueKind::Array => Self::ManifestProofs(
190 Vec::<ManifestProof>::decode_body_with_value_kind(decoder, value_kind)?,
191 ),
192 ValueKind::Custom(_) => {
193 let expression =
194 ManifestExpression::decode_body_with_value_kind(decoder, value_kind)?;
195 if !matches!(expression, ManifestExpression::EntireAuthZone) {
196 return Err(sbor::DecodeError::InvalidCustomValue);
197 }
198 Self::EntireAuthZone
199 }
200 _ => {
201 return Err(sbor::DecodeError::UnexpectedValueKind {
202 expected: ManifestValueKind::Array.as_u8(),
203 actual: value_kind.as_u8(),
204 });
205 }
206 })
207 }
208}
209
210impl sbor::Describe<ScryptoCustomTypeKind> for ManifestProofBatch {
211 const TYPE_ID: sbor::RustTypeId = Vec::<ManifestProof>::TYPE_ID;
212
213 fn type_data() -> sbor::TypeData<ScryptoCustomTypeKind, sbor::RustTypeId> {
214 Vec::<ManifestProof>::type_data()
215 }
216}
217
218#[derive(Debug, Clone, PartialEq, Eq)]
224pub enum ParseManifestExpressionError {
225 InvalidLength,
226 UnknownExpression,
227}
228
229#[cfg(not(feature = "alloc"))]
230impl std::error::Error for ParseManifestExpressionError {}
231
232#[cfg(not(feature = "alloc"))]
233impl fmt::Display for ParseManifestExpressionError {
234 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
235 write!(f, "{:?}", self)
236 }
237}
238
239impl TryFrom<&[u8]> for ManifestExpression {
244 type Error = ParseManifestExpressionError;
245
246 fn try_from(slice: &[u8]) -> Result<Self, Self::Error> {
247 if slice.len() != 1 {
248 return Err(Self::Error::InvalidLength);
249 }
250 match slice[0] {
251 0 => Ok(Self::EntireWorktop),
252 1 => Ok(Self::EntireAuthZone),
253 _ => Err(Self::Error::UnknownExpression),
254 }
255 }
256}
257
258impl ManifestExpression {
259 pub fn to_vec(&self) -> Vec<u8> {
260 let mut bytes = Vec::new();
261 match self {
262 ManifestExpression::EntireWorktop => {
263 bytes.push(0);
264 }
265 ManifestExpression::EntireAuthZone => {
266 bytes.push(1);
267 }
268 };
269 bytes
270 }
271}
272
273manifest_type!(ManifestExpression, ManifestCustomValueKind::Expression, 1);
274
275#[cfg(test)]
276mod tests {
277 use super::*;
278
279 #[test]
280 fn manifest_expression_parse_fail() {
281 let vec_err_1 = vec![1u8, 2];
283 let vec_err_2 = vec![10u8];
285
286 let err1 = ManifestExpression::try_from(vec_err_1.as_slice());
287 assert_matches!(err1, Err(ParseManifestExpressionError::InvalidLength));
288 #[cfg(not(feature = "alloc"))]
289 println!("Decoding manifest expression error: {}", err1.unwrap_err());
290
291 let err2 = ManifestExpression::try_from(vec_err_2.as_slice());
292 assert_matches!(err2, Err(ParseManifestExpressionError::UnknownExpression));
293 #[cfg(not(feature = "alloc"))]
294 println!("Decoding manifest expression error: {}", err2.unwrap_err());
295 }
296
297 #[test]
298 fn manifest_expression_discriminator_fail() {
299 let mut buf = Vec::new();
300 let mut encoder = VecEncoder::<ManifestCustomValueKind>::new(&mut buf, 1);
301 encoder.write_discriminator(0xff).unwrap();
303
304 let mut decoder = VecDecoder::<ManifestCustomValueKind>::new(&buf, 1);
305 let addr_output = decoder.decode_deeper_body_with_value_kind::<ManifestExpression>(
306 ManifestExpression::value_kind(),
307 );
308
309 assert_matches!(addr_output, Err(DecodeError::InvalidCustomValue));
310 }
311}