radix_common/
macros.rs

1/// Creates a safe integer from literals.
2/// You must specify the type of the
3/// integer you want to create.
4///
5#[macro_export]
6macro_rules! i {
7    ($x:expr) => {
8        $x.try_into().expect("Parse Error")
9    };
10}
11
12/// A macro for implementing sbor traits (for statically sized types).
13#[macro_export]
14macro_rules! well_known_scrypto_custom_type {
15    // with describe
16    ($t:ty, $value_kind:expr, $schema_type:expr, $size:expr, $well_known_type:ident, $well_known_type_data_method:ident$(,)?) => {
17        impl sbor::Categorize<$crate::data::scrypto::ScryptoCustomValueKind> for $t {
18            #[inline]
19            fn value_kind() -> sbor::ValueKind<$crate::data::scrypto::ScryptoCustomValueKind> {
20                sbor::ValueKind::Custom($value_kind)
21            }
22        }
23
24        impl<E: sbor::Encoder<$crate::data::scrypto::ScryptoCustomValueKind>>
25            sbor::Encode<$crate::data::scrypto::ScryptoCustomValueKind, E> for $t
26        {
27            #[inline]
28            fn encode_value_kind(&self, encoder: &mut E) -> Result<(), sbor::EncodeError> {
29                encoder.write_value_kind(Self::value_kind())
30            }
31
32            #[inline]
33            fn encode_body(&self, encoder: &mut E) -> Result<(), sbor::EncodeError> {
34                encoder.write_slice(&self.to_vec())
35            }
36        }
37
38        impl<D: sbor::Decoder<$crate::data::scrypto::ScryptoCustomValueKind>>
39            sbor::Decode<$crate::data::scrypto::ScryptoCustomValueKind, D> for $t
40        {
41            fn decode_body_with_value_kind(
42                decoder: &mut D,
43                value_kind: sbor::ValueKind<$crate::data::scrypto::ScryptoCustomValueKind>,
44            ) -> Result<Self, sbor::DecodeError> {
45                decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
46                let slice = decoder.read_slice($size)?;
47                Self::try_from(slice).map_err(|_| sbor::DecodeError::InvalidCustomValue)
48            }
49        }
50
51        impl sbor::Describe<$crate::data::scrypto::ScryptoCustomTypeKind> for $t {
52            const TYPE_ID: sbor::RustTypeId = sbor::RustTypeId::WellKnown(
53                $crate::data::scrypto::well_known_scrypto_custom_types::$well_known_type,
54            );
55
56            fn type_data() -> sbor::TypeData<$crate::data::scrypto::ScryptoCustomTypeKind, sbor::RustTypeId> {
57                $crate::data::scrypto::well_known_scrypto_custom_types::$well_known_type_data_method()
58            }
59        }
60    };
61}
62
63#[macro_export]
64macro_rules! manifest_type {
65    // Without describe - if you need describe, also use scrypto_describe_for_manifest_type!
66    ($t:ty, $value_kind:expr, $size: expr$(,)?) => {
67        impl sbor::Categorize<$crate::data::manifest::ManifestCustomValueKind> for $t {
68            #[inline]
69            fn value_kind() -> sbor::ValueKind<$crate::data::manifest::ManifestCustomValueKind> {
70                sbor::ValueKind::Custom($value_kind)
71            }
72        }
73
74        impl<E: sbor::Encoder<$crate::data::manifest::ManifestCustomValueKind>>
75            sbor::Encode<$crate::data::manifest::ManifestCustomValueKind, E> for $t
76        {
77            #[inline]
78            fn encode_value_kind(&self, encoder: &mut E) -> Result<(), sbor::EncodeError> {
79                encoder.write_value_kind(Self::value_kind())
80            }
81
82            #[inline]
83            fn encode_body(&self, encoder: &mut E) -> Result<(), sbor::EncodeError> {
84                encoder.write_slice(&self.to_vec())
85            }
86        }
87
88        impl<D: sbor::Decoder<$crate::data::manifest::ManifestCustomValueKind>>
89            sbor::Decode<$crate::data::manifest::ManifestCustomValueKind, D> for $t
90        {
91            fn decode_body_with_value_kind(
92                decoder: &mut D,
93                value_kind: sbor::ValueKind<$crate::data::manifest::ManifestCustomValueKind>,
94            ) -> Result<Self, sbor::DecodeError> {
95                decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
96                let slice = decoder.read_slice($size)?;
97                Self::try_from(slice).map_err(|_| sbor::DecodeError::InvalidCustomValue)
98            }
99        }
100    };
101}
102
103#[macro_export]
104macro_rules! scrypto_describe_for_manifest_type {
105    ($t:ty, $well_known_type:ident, $well_known_type_data_method:ident$(,)?) => {
106        impl sbor::Describe<$crate::data::scrypto::ScryptoCustomTypeKind> for $t {
107            const TYPE_ID: sbor::RustTypeId = sbor::RustTypeId::WellKnown(
108                $crate::data::scrypto::well_known_scrypto_custom_types::$well_known_type,
109            );
110
111            fn type_data() -> sbor::TypeData<$crate::data::scrypto::ScryptoCustomTypeKind, sbor::RustTypeId> {
112                $crate::data::scrypto::well_known_scrypto_custom_types::$well_known_type_data_method()
113            }
114        }
115    }
116}
117
118#[macro_export]
119macro_rules! count {
120    () => {0usize};
121    ($a:expr) => {1usize};
122    ($a:expr, $($rest:expr),*) => {1usize + $crate::count!($($rest),*)};
123}
124
125#[macro_export]
126macro_rules! scrypto_args {
127    ($($args: expr),*) => {{
128        use sbor::Encoder;
129        let mut buf = sbor::rust::vec::Vec::new();
130        let mut encoder = $crate::data::scrypto::ScryptoEncoder::new(
131            &mut buf,
132            $crate::data::scrypto::SCRYPTO_SBOR_V1_MAX_DEPTH,
133        );
134        encoder
135            .write_payload_prefix($crate::data::scrypto::SCRYPTO_SBOR_V1_PAYLOAD_PREFIX)
136            .unwrap();
137        encoder
138            .write_value_kind($crate::data::scrypto::ScryptoValueKind::Tuple)
139            .unwrap();
140        // Hack: stringify to skip ownership move semantics
141        encoder.write_size($crate::count!($(stringify!($args)),*)).unwrap();
142        $(
143            let arg = $args;
144            encoder.encode(&arg).unwrap();
145        )*
146        buf
147    }};
148}
149
150#[macro_export]
151macro_rules! manifest_args {
152    ($($args: expr),*$(,)?) => {{
153        use sbor::Encoder;
154        let mut buf = sbor::rust::vec::Vec::new();
155        let mut encoder = $crate::data::manifest::ManifestEncoder::new(&mut buf, $crate::data::manifest::MANIFEST_SBOR_V1_MAX_DEPTH);
156        encoder.write_payload_prefix($crate::data::manifest::MANIFEST_SBOR_V1_PAYLOAD_PREFIX).unwrap();
157        encoder.write_value_kind($crate::data::manifest::ManifestValueKind::Tuple).unwrap();
158        // Hack: stringify to skip ownership move semantics
159        encoder.write_size($crate::count!($(stringify!($args)),*)).unwrap();
160        $(
161            let arg = $args;
162            encoder.encode(&arg).unwrap();
163        )*
164        let value = $crate::data::manifest::manifest_decode(&buf).unwrap();
165        ManifestArgs::new_from_tuple_or_panic(value)
166    }};
167}
168
169#[macro_export]
170macro_rules! to_manifest_value_and_unwrap {
171    ( $value:expr ) => {{
172        $crate::data::manifest::to_manifest_value($value).unwrap()
173    }};
174}