radix_common/data/manifest/model/
manifest_address.rs1use crate::data::manifest::ManifestCustomValueKind;
2use crate::types::EntityType;
3use crate::types::NodeId;
4use crate::*;
5
6use sbor::rust::fmt;
7use sbor::*;
8
9#[cfg_attr(
13 feature = "fuzzing",
14 derive(::arbitrary::Arbitrary, ::serde::Serialize, ::serde::Deserialize)
15)]
16#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
17#[must_use]
18pub enum ManifestAddress {
19 Static(NodeId),
22 Named(ManifestNamedAddress),
24}
25
26impl ManifestAddress {
27 pub fn named(id: u32) -> Self {
28 Self::Named(ManifestNamedAddress(id))
29 }
30
31 pub fn into_named(self) -> Option<ManifestNamedAddress> {
32 match self {
33 ManifestAddress::Static(_) => None,
34 ManifestAddress::Named(named) => Some(named),
35 }
36 }
37}
38
39#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, ManifestSbor)]
40#[sbor(
41 as_type = "ManifestAddress",
42 as_ref = "&ManifestAddress::Named(*self)",
43 from_value = "value.into_named().ok_or(DecodeError::InvalidCustomValue)?"
44)]
45#[cfg_attr(
46 feature = "fuzzing",
47 derive(::arbitrary::Arbitrary, ::serde::Serialize, ::serde::Deserialize)
48)]
49pub struct ManifestNamedAddress(pub u32);
50
51pub const MANIFEST_ADDRESS_DISCRIMINATOR_STATIC: u8 = 0u8;
52pub const MANIFEST_ADDRESS_DISCRIMINATOR_NAMED: u8 = 1u8;
53
54impl From<ManifestNamedAddress> for ManifestAddress {
55 fn from(value: ManifestNamedAddress) -> Self {
56 Self::Named(value)
57 }
58}
59
60impl Categorize<ManifestCustomValueKind> for ManifestAddress {
65 #[inline]
66 fn value_kind() -> ValueKind<ManifestCustomValueKind> {
67 ValueKind::Custom(ManifestCustomValueKind::Address)
68 }
69}
70
71impl<E: Encoder<ManifestCustomValueKind>> Encode<ManifestCustomValueKind, E> for ManifestAddress {
72 #[inline]
73 fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
74 encoder.write_value_kind(Self::value_kind())
75 }
76
77 #[inline]
78 fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
79 match self {
80 Self::Static(node_id) => {
81 encoder.write_discriminator(MANIFEST_ADDRESS_DISCRIMINATOR_STATIC)?;
82 encoder.write_slice(node_id.as_bytes())?;
83 }
84 Self::Named(address_id) => {
85 encoder.write_discriminator(MANIFEST_ADDRESS_DISCRIMINATOR_NAMED)?;
86 encoder.write_slice(&address_id.0.to_le_bytes())?;
87 }
88 }
89 Ok(())
90 }
91}
92
93impl<D: Decoder<ManifestCustomValueKind>> Decode<ManifestCustomValueKind, D> for ManifestAddress {
94 fn decode_body_with_value_kind(
95 decoder: &mut D,
96 value_kind: ValueKind<ManifestCustomValueKind>,
97 ) -> Result<Self, DecodeError> {
98 decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
99 match decoder.read_discriminator()? {
100 MANIFEST_ADDRESS_DISCRIMINATOR_STATIC => {
101 let slice = decoder.read_slice(NodeId::LENGTH)?;
102 if EntityType::from_repr(slice[0]).is_none() {
103 return Err(DecodeError::InvalidCustomValue);
104 }
105 Ok(Self::Static(NodeId(slice.try_into().unwrap())))
106 }
107 MANIFEST_ADDRESS_DISCRIMINATOR_NAMED => {
108 let slice = decoder.read_slice(4)?;
109 let id = u32::from_le_bytes(slice.try_into().unwrap());
110 Ok(Self::Named(ManifestNamedAddress(id)))
111 }
112 _ => Err(DecodeError::InvalidCustomValue),
113 }
114 }
115}
116
117impl fmt::Debug for ManifestAddress {
122 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
123 match self {
124 ManifestAddress::Static(node_id) => {
125 write!(f, "Address({})", hex::encode(node_id.as_bytes()))
126 }
127 ManifestAddress::Named(name) => write!(f, "{name:?}"),
128 }
129 }
130}
131
132impl fmt::Debug for ManifestNamedAddress {
133 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
134 write!(f, "NamedAddress({})", self.0)
135 }
136}
137
138#[cfg(test)]
139mod tests {
140 use super::*;
141 use crate::internal_prelude::*;
142 #[cfg(feature = "alloc")]
143 use sbor::prelude::Vec;
144
145 fn prepare_address(
146 addr_input: &(impl ManifestEncode + Debug),
147 ) -> Result<ManifestAddress, sbor::DecodeError> {
148 #[cfg(not(feature = "alloc"))]
149 println!("Encoding manifest address: {:?}", addr_input);
150 let mut buf = Vec::new();
151 let mut encoder = VecEncoder::<ManifestCustomValueKind>::new(&mut buf, 1);
152 assert!(addr_input.encode_body(&mut encoder).is_ok());
153 let mut decoder = VecDecoder::<ManifestCustomValueKind>::new(&buf, 1);
154 decoder.decode_deeper_body_with_value_kind::<ManifestAddress>(ManifestAddress::value_kind())
155 }
156
157 #[test]
158 fn manifest_address_decode_static_success() {
159 let node_id = NodeId::new(EntityType::GlobalPackage as u8, &[0; NodeId::RID_LENGTH]);
160 let addr_input = ManifestAddress::Static(node_id);
161 let addr_output = prepare_address(&addr_input);
162 assert!(addr_output.is_ok());
163 assert_eq!(addr_input, addr_output.unwrap());
164 }
165
166 #[test]
167 fn manifest_address_decode_named_success() {
168 let addr_input = ManifestAddress::named(1);
169 let addr_input2 = ManifestNamedAddress(1);
170 let addr_output = prepare_address(&addr_input);
171 let addr_output2 = prepare_address(&addr_input2);
172 assert!(addr_output.is_ok());
173 assert_eq!(addr_input, addr_output.unwrap());
174 assert_eq!(addr_input, addr_output2.unwrap());
175 }
176
177 #[test]
178 fn manifest_address_decode_static_fail() {
179 let node_id = NodeId::new(0, &[0; NodeId::RID_LENGTH]);
181 let addr_input = ManifestAddress::Static(node_id);
182 let addr_output = prepare_address(&addr_input);
183 assert_matches!(addr_output, Err(DecodeError::InvalidCustomValue));
184 }
185
186 #[test]
187 fn manifest_address_decode_named_fail() {
188 let mut buf = Vec::new();
189 let mut encoder = VecEncoder::<ManifestCustomValueKind>::new(&mut buf, 1);
190 encoder
191 .write_discriminator(MANIFEST_ADDRESS_DISCRIMINATOR_NAMED)
192 .unwrap();
193 let malformed_value: u8 = 1; encoder.write_slice(&malformed_value.to_le_bytes()).unwrap();
195
196 let mut decoder = VecDecoder::<ManifestCustomValueKind>::new(&buf, 1);
197 let addr_output = decoder
198 .decode_deeper_body_with_value_kind::<ManifestAddress>(ManifestAddress::value_kind());
199
200 assert_matches!(addr_output, Err(DecodeError::BufferUnderflow { .. }));
202 }
203
204 #[test]
205 fn manifest_address_decode_discriminator_fail() {
206 let mut buf = Vec::new();
207 let mut encoder = VecEncoder::<ManifestCustomValueKind>::new(&mut buf, 1);
208 encoder.write_discriminator(0xff).unwrap();
210
211 let mut decoder = VecDecoder::<ManifestCustomValueKind>::new(&buf, 1);
212 let addr_output = decoder
213 .decode_deeper_body_with_value_kind::<ManifestAddress>(ManifestAddress::value_kind());
214
215 assert_matches!(addr_output, Err(DecodeError::InvalidCustomValue));
216 }
217}