radix_common/data/manifest/model/
manifest_address_kinds.rs1use crate::internal_prelude::*;
2use radix_common::scrypto_describe_for_manifest_type;
3use sbor::{Decoder, Encoder};
4
5macro_rules! labelled_resolvable_address {
43 ($ty:ty$(,)?) => {
44 resolvable_with_try_into_impls!($ty);
45 labelled_resolvable_using_resolvable_impl!($ty, resolver_output: ManifestNamedAddress);
46
47 impl<'a> LabelledResolveFrom<&'a str> for $ty {
48 fn labelled_resolve_from(value: &'a str, resolver: &impl LabelResolver<ManifestNamedAddress>) -> Self {
49 resolver.resolve_label_into(value).into()
50 }
51 }
52
53 impl<'a> LabelledResolveFrom<&'a String> for $ty {
54 fn labelled_resolve_from(value: &'a String, resolver: &impl LabelResolver<ManifestNamedAddress>) -> Self {
55 resolver.resolve_label_into(value.as_str()).into()
56 }
57 }
58
59 impl<'a> LabelledResolveFrom<String> for $ty {
60 fn labelled_resolve_from(value: String, resolver: &impl LabelResolver<ManifestNamedAddress>) -> Self {
61 resolver.resolve_label_into(value.as_str()).into()
62 }
63 }
64 };
65}
66
67pub trait IntoManifestAddress {
68 type ManifestAddress;
69
70 fn into_manifest_address(self) -> Self::ManifestAddress;
71}
72
73pub type DynamicGlobalAddress = ManifestGlobalAddress;
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
77pub enum ManifestGlobalAddress {
78 Static(GlobalAddress),
79 Named(ManifestNamedAddress),
80}
81
82impl IntoManifestAddress for GlobalAddress {
83 type ManifestAddress = ManifestGlobalAddress;
84
85 fn into_manifest_address(self) -> Self::ManifestAddress {
86 Self::ManifestAddress::Static(self)
87 }
88}
89
90scrypto_describe_for_manifest_type!(
91 ManifestGlobalAddress,
92 GLOBAL_ADDRESS_TYPE,
93 global_address_type_data,
94);
95
96labelled_resolvable_address!(ManifestGlobalAddress);
97
98impl Categorize<ManifestCustomValueKind> for ManifestGlobalAddress {
99 #[inline]
100 fn value_kind() -> ValueKind<ManifestCustomValueKind> {
101 ValueKind::Custom(ManifestCustomValueKind::Address)
102 }
103}
104
105impl<E: Encoder<ManifestCustomValueKind>> Encode<ManifestCustomValueKind, E>
106 for ManifestGlobalAddress
107{
108 #[inline]
109 fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
110 encoder.write_value_kind(Self::value_kind())
111 }
112
113 #[inline]
114 fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
115 match self {
116 Self::Static(address) => {
117 encoder.write_discriminator(MANIFEST_ADDRESS_DISCRIMINATOR_STATIC)?;
118 encoder.write_slice(address.as_node_id().as_bytes())?;
119 }
120 Self::Named(address_id) => {
121 encoder.write_discriminator(MANIFEST_ADDRESS_DISCRIMINATOR_NAMED)?;
122 encoder.write_slice(&address_id.0.to_le_bytes())?;
123 }
124 }
125 Ok(())
126 }
127}
128
129impl<D: Decoder<ManifestCustomValueKind>> Decode<ManifestCustomValueKind, D>
130 for ManifestGlobalAddress
131{
132 fn decode_body_with_value_kind(
133 decoder: &mut D,
134 value_kind: ValueKind<ManifestCustomValueKind>,
135 ) -> Result<Self, DecodeError> {
136 decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
137 match decoder.read_discriminator()? {
138 MANIFEST_ADDRESS_DISCRIMINATOR_STATIC => {
139 let slice = decoder.read_slice(NodeId::LENGTH)?;
140 Ok(Self::Static(
141 GlobalAddress::try_from(slice).map_err(|_| DecodeError::InvalidCustomValue)?,
142 ))
143 }
144 MANIFEST_ADDRESS_DISCRIMINATOR_NAMED => {
145 let slice = decoder.read_slice(4)?;
146 let id = u32::from_le_bytes(slice.try_into().unwrap());
147 Ok(Self::Named(ManifestNamedAddress(id)))
148 }
149 _ => Err(DecodeError::InvalidCustomValue),
150 }
151 }
152}
153
154impl ManifestGlobalAddress {
155 pub fn to_instruction_argument(&self) -> ManifestValue {
158 match self {
159 Self::Static(address) => ManifestValue::Custom {
160 value: ManifestCustomValue::Address(ManifestAddress::Static(
161 address.into_node_id(),
162 )),
163 },
164 Self::Named(id) => ManifestValue::Custom {
165 value: ManifestCustomValue::Address(ManifestAddress::Named(*id)),
166 },
167 }
168 }
169
170 pub fn is_static_global_package(&self) -> bool {
171 match self {
172 Self::Static(address) => address.as_node_id().is_global_package(),
173 Self::Named(_) => false,
174 }
175 }
176
177 pub fn is_static_global_fungible_resource_manager(&self) -> bool {
178 match self {
179 Self::Static(address) => address.as_node_id().is_global_fungible_resource_manager(),
180 Self::Named(_) => false,
181 }
182 }
183 pub fn is_static_global_non_fungible_resource_manager(&self) -> bool {
184 match self {
185 Self::Static(address) => address
186 .as_node_id()
187 .is_global_non_fungible_resource_manager(),
188 Self::Named(_) => false,
189 }
190 }
191}
192
193impl From<GlobalAddress> for ManifestGlobalAddress {
194 fn from(value: GlobalAddress) -> Self {
195 Self::Static(value)
196 }
197}
198
199impl From<PackageAddress> for ManifestGlobalAddress {
200 fn from(value: PackageAddress) -> Self {
201 Self::Static(value.into())
202 }
203}
204
205impl From<ManifestPackageAddress> for ManifestGlobalAddress {
206 fn from(value: ManifestPackageAddress) -> Self {
207 match value {
208 ManifestPackageAddress::Static(value) => Self::Static(value.into()),
209 ManifestPackageAddress::Named(value) => Self::Named(value),
210 }
211 }
212}
213
214impl From<ResourceAddress> for ManifestGlobalAddress {
215 fn from(value: ResourceAddress) -> Self {
216 Self::Static(value.into())
217 }
218}
219
220impl From<ManifestResourceAddress> for ManifestGlobalAddress {
221 fn from(value: ManifestResourceAddress) -> Self {
222 match value {
223 ManifestResourceAddress::Static(value) => Self::Static(value.into()),
224 ManifestResourceAddress::Named(value) => Self::Named(value),
225 }
226 }
227}
228
229impl From<ComponentAddress> for ManifestGlobalAddress {
230 fn from(value: ComponentAddress) -> Self {
231 Self::Static(value.into())
232 }
233}
234
235impl From<ManifestComponentAddress> for ManifestGlobalAddress {
236 fn from(value: ManifestComponentAddress) -> Self {
237 match value {
238 ManifestComponentAddress::Static(value) => Self::Static(value.into()),
239 ManifestComponentAddress::Named(value) => Self::Named(value),
240 }
241 }
242}
243
244impl From<ManifestNamedAddress> for ManifestGlobalAddress {
245 fn from(value: ManifestNamedAddress) -> Self {
246 Self::Named(value)
247 }
248}
249
250impl TryFrom<ManifestAddress> for ManifestGlobalAddress {
251 type Error = ParseGlobalAddressError;
252
253 fn try_from(value: ManifestAddress) -> Result<Self, Self::Error> {
254 Ok(match value {
255 ManifestAddress::Static(value) => Self::Static(value.try_into()?),
256 ManifestAddress::Named(value) => Self::Named(value),
257 })
258 }
259}
260
261pub type DynamicPackageAddress = ManifestPackageAddress;
263
264#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
265pub enum ManifestPackageAddress {
266 Static(PackageAddress),
267 Named(ManifestNamedAddress),
268}
269
270impl IntoManifestAddress for PackageAddress {
271 type ManifestAddress = ManifestPackageAddress;
272
273 fn into_manifest_address(self) -> Self::ManifestAddress {
274 Self::ManifestAddress::Static(self)
275 }
276}
277
278scrypto_describe_for_manifest_type!(
279 ManifestPackageAddress,
280 PACKAGE_ADDRESS_TYPE,
281 package_address_type_data,
282);
283
284labelled_resolvable_address!(ManifestPackageAddress);
285
286impl Categorize<ManifestCustomValueKind> for ManifestPackageAddress {
287 #[inline]
288 fn value_kind() -> ValueKind<ManifestCustomValueKind> {
289 ValueKind::Custom(ManifestCustomValueKind::Address)
290 }
291}
292
293impl<E: Encoder<ManifestCustomValueKind>> Encode<ManifestCustomValueKind, E>
294 for ManifestPackageAddress
295{
296 #[inline]
297 fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
298 encoder.write_value_kind(Self::value_kind())
299 }
300
301 #[inline]
302 fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
303 match self {
304 Self::Static(address) => {
305 encoder.write_discriminator(0)?;
306 encoder.write_slice(address.as_node_id().as_bytes())?;
307 }
308 Self::Named(address_id) => {
309 encoder.write_discriminator(1)?;
310 encoder.write_slice(&address_id.0.to_le_bytes())?;
311 }
312 }
313 Ok(())
314 }
315}
316
317impl<D: Decoder<ManifestCustomValueKind>> Decode<ManifestCustomValueKind, D>
318 for ManifestPackageAddress
319{
320 fn decode_body_with_value_kind(
321 decoder: &mut D,
322 value_kind: ValueKind<ManifestCustomValueKind>,
323 ) -> Result<Self, DecodeError> {
324 decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
325 match decoder.read_discriminator()? {
326 MANIFEST_ADDRESS_DISCRIMINATOR_STATIC => {
327 let slice = decoder.read_slice(NodeId::LENGTH)?;
328 Ok(Self::Static(
329 PackageAddress::try_from(slice).map_err(|_| DecodeError::InvalidCustomValue)?,
330 ))
331 }
332 MANIFEST_ADDRESS_DISCRIMINATOR_NAMED => {
333 let slice = decoder.read_slice(4)?;
334 let id = u32::from_le_bytes(slice.try_into().unwrap());
335 Ok(Self::Named(ManifestNamedAddress(id)))
336 }
337 _ => Err(DecodeError::InvalidCustomValue),
338 }
339 }
340}
341
342impl ManifestPackageAddress {
343 pub fn to_instruction_argument(&self) -> ManifestValue {
346 match self {
347 Self::Static(address) => ManifestValue::Custom {
348 value: ManifestCustomValue::Address(ManifestAddress::Static(
349 address.into_node_id(),
350 )),
351 },
352 Self::Named(id) => ManifestValue::Custom {
353 value: ManifestCustomValue::Address(ManifestAddress::Named(*id)),
354 },
355 }
356 }
357
358 pub fn is_static_global_package_of(&self, package_address: &PackageAddress) -> bool {
359 match self {
360 Self::Static(address) => address.as_node_id().eq(package_address.as_node_id()),
361 Self::Named(_) => false,
362 }
363 }
364}
365
366impl From<PackageAddress> for ManifestPackageAddress {
367 fn from(value: PackageAddress) -> Self {
368 Self::Static(value)
369 }
370}
371
372impl From<ManifestNamedAddress> for ManifestPackageAddress {
373 fn from(value: ManifestNamedAddress) -> Self {
374 Self::Named(value)
375 }
376}
377
378impl TryFrom<GlobalAddress> for ManifestPackageAddress {
379 type Error = ParsePackageAddressError;
380
381 fn try_from(value: GlobalAddress) -> Result<Self, Self::Error> {
382 Ok(Self::Static(PackageAddress::try_from(
383 value.into_node_id(),
384 )?))
385 }
386}
387
388impl TryFrom<ManifestAddress> for ManifestPackageAddress {
389 type Error = ParsePackageAddressError;
390
391 fn try_from(value: ManifestAddress) -> Result<Self, Self::Error> {
392 Ok(match value {
393 ManifestAddress::Static(value) => Self::Static(value.try_into()?),
394 ManifestAddress::Named(value) => Self::Named(value),
395 })
396 }
397}
398
399pub trait ResolvableStaticManifestPackageAddress: Sized {
405 fn resolve_static(self) -> PackageAddress;
406}
407
408impl<A, E> ResolvableStaticManifestPackageAddress for A
409where
410 A: TryInto<ManifestPackageAddress, Error = E>,
411 E: Debug,
412{
413 fn resolve_static(self) -> PackageAddress {
414 let address = self
415 .try_into()
416 .expect("Address was not a valid ManifestPackageAddress");
417 match address {
418 ManifestPackageAddress::Static(address) => address,
419 ManifestPackageAddress::Named(_) => {
420 panic!("This address needs to be a static/fixed address")
421 }
422 }
423 }
424}
425
426pub type DynamicComponentAddress = ManifestComponentAddress;
428
429#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
430pub enum ManifestComponentAddress {
431 Static(ComponentAddress),
432 Named(ManifestNamedAddress),
433}
434
435impl IntoManifestAddress for ComponentAddress {
436 type ManifestAddress = ManifestComponentAddress;
437
438 fn into_manifest_address(self) -> Self::ManifestAddress {
439 Self::ManifestAddress::Static(self)
440 }
441}
442
443scrypto_describe_for_manifest_type!(
444 ManifestComponentAddress,
445 COMPONENT_ADDRESS_TYPE,
446 component_address_type_data,
447);
448
449labelled_resolvable_address!(ManifestComponentAddress);
450
451impl Categorize<ManifestCustomValueKind> for ManifestComponentAddress {
452 #[inline]
453 fn value_kind() -> ValueKind<ManifestCustomValueKind> {
454 ValueKind::Custom(ManifestCustomValueKind::Address)
455 }
456}
457
458impl<E: Encoder<ManifestCustomValueKind>> Encode<ManifestCustomValueKind, E>
459 for ManifestComponentAddress
460{
461 #[inline]
462 fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
463 encoder.write_value_kind(Self::value_kind())
464 }
465
466 #[inline]
467 fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
468 match self {
469 Self::Static(address) => {
470 encoder.write_discriminator(MANIFEST_ADDRESS_DISCRIMINATOR_STATIC)?;
471 encoder.write_slice(address.as_node_id().as_bytes())?;
472 }
473 Self::Named(address_id) => {
474 encoder.write_discriminator(MANIFEST_ADDRESS_DISCRIMINATOR_NAMED)?;
475 encoder.write_slice(&address_id.0.to_le_bytes())?;
476 }
477 }
478 Ok(())
479 }
480}
481
482impl<D: Decoder<ManifestCustomValueKind>> Decode<ManifestCustomValueKind, D>
483 for ManifestComponentAddress
484{
485 fn decode_body_with_value_kind(
486 decoder: &mut D,
487 value_kind: ValueKind<ManifestCustomValueKind>,
488 ) -> Result<Self, DecodeError> {
489 decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
490 match decoder.read_discriminator()? {
491 MANIFEST_ADDRESS_DISCRIMINATOR_STATIC => {
492 let slice = decoder.read_slice(NodeId::LENGTH)?;
493 Ok(Self::Static(
494 ComponentAddress::try_from(slice)
495 .map_err(|_| DecodeError::InvalidCustomValue)?,
496 ))
497 }
498 MANIFEST_ADDRESS_DISCRIMINATOR_NAMED => {
499 let slice = decoder.read_slice(4)?;
500 let id = u32::from_le_bytes(slice.try_into().unwrap());
501 Ok(Self::Named(ManifestNamedAddress(id)))
502 }
503 _ => Err(DecodeError::InvalidCustomValue),
504 }
505 }
506}
507
508impl From<ComponentAddress> for ManifestComponentAddress {
509 fn from(value: ComponentAddress) -> Self {
510 Self::Static(value)
511 }
512}
513
514impl From<ManifestNamedAddress> for ManifestComponentAddress {
515 fn from(value: ManifestNamedAddress) -> Self {
516 Self::Named(value)
517 }
518}
519
520impl TryFrom<GlobalAddress> for ManifestComponentAddress {
521 type Error = ParseComponentAddressError;
522
523 fn try_from(value: GlobalAddress) -> Result<Self, Self::Error> {
524 Ok(Self::Static(ComponentAddress::try_from(
525 value.into_node_id(),
526 )?))
527 }
528}
529
530impl TryFrom<ManifestAddress> for ManifestComponentAddress {
531 type Error = ParseComponentAddressError;
532
533 fn try_from(value: ManifestAddress) -> Result<Self, Self::Error> {
534 Ok(match value {
535 ManifestAddress::Static(value) => Self::Static(value.try_into()?),
536 ManifestAddress::Named(value) => Self::Named(value),
537 })
538 }
539}
540
541pub type DynamicResourceAddress = ManifestResourceAddress;
543
544#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
545pub enum ManifestResourceAddress {
546 Static(ResourceAddress),
547 Named(ManifestNamedAddress),
548}
549
550impl IntoManifestAddress for ResourceAddress {
551 type ManifestAddress = ManifestResourceAddress;
552
553 fn into_manifest_address(self) -> Self::ManifestAddress {
554 Self::ManifestAddress::Static(self)
555 }
556}
557
558scrypto_describe_for_manifest_type!(
559 ManifestResourceAddress,
560 RESOURCE_ADDRESS_TYPE,
561 resource_address_type_data,
562);
563
564labelled_resolvable_address!(ManifestResourceAddress);
565
566impl Categorize<ManifestCustomValueKind> for ManifestResourceAddress {
567 #[inline]
568 fn value_kind() -> ValueKind<ManifestCustomValueKind> {
569 ValueKind::Custom(ManifestCustomValueKind::Address)
570 }
571}
572
573impl<E: Encoder<ManifestCustomValueKind>> Encode<ManifestCustomValueKind, E>
574 for ManifestResourceAddress
575{
576 #[inline]
577 fn encode_value_kind(&self, encoder: &mut E) -> Result<(), EncodeError> {
578 encoder.write_value_kind(Self::value_kind())
579 }
580
581 #[inline]
582 fn encode_body(&self, encoder: &mut E) -> Result<(), EncodeError> {
583 match self {
584 Self::Static(address) => {
585 encoder.write_discriminator(MANIFEST_ADDRESS_DISCRIMINATOR_STATIC)?;
586 encoder.write_slice(address.as_node_id().as_bytes())?;
587 }
588 Self::Named(address_id) => {
589 encoder.write_discriminator(MANIFEST_ADDRESS_DISCRIMINATOR_NAMED)?;
590 encoder.write_slice(&address_id.0.to_le_bytes())?;
591 }
592 }
593 Ok(())
594 }
595}
596
597impl<D: Decoder<ManifestCustomValueKind>> Decode<ManifestCustomValueKind, D>
598 for ManifestResourceAddress
599{
600 fn decode_body_with_value_kind(
601 decoder: &mut D,
602 value_kind: ValueKind<ManifestCustomValueKind>,
603 ) -> Result<Self, DecodeError> {
604 decoder.check_preloaded_value_kind(value_kind, Self::value_kind())?;
605 match decoder.read_discriminator()? {
606 MANIFEST_ADDRESS_DISCRIMINATOR_STATIC => {
607 let slice = decoder.read_slice(NodeId::LENGTH)?;
608 Ok(Self::Static(
609 ResourceAddress::try_from(slice)
610 .map_err(|_| DecodeError::InvalidCustomValue)?,
611 ))
612 }
613 MANIFEST_ADDRESS_DISCRIMINATOR_NAMED => {
614 let slice = decoder.read_slice(4)?;
615 let id = u32::from_le_bytes(slice.try_into().unwrap());
616 Ok(Self::Named(ManifestNamedAddress(id)))
617 }
618 _ => Err(DecodeError::InvalidCustomValue),
619 }
620 }
621}
622
623impl From<ResourceAddress> for ManifestResourceAddress {
624 fn from(value: ResourceAddress) -> Self {
625 Self::Static(value)
626 }
627}
628
629impl From<ManifestNamedAddress> for ManifestResourceAddress {
630 fn from(value: ManifestNamedAddress) -> Self {
631 Self::Named(value)
632 }
633}
634
635impl TryFrom<GlobalAddress> for ManifestResourceAddress {
636 type Error = ParseResourceAddressError;
637
638 fn try_from(value: GlobalAddress) -> Result<Self, Self::Error> {
639 Ok(Self::Static(ResourceAddress::try_from(
640 value.into_node_id(),
641 )?))
642 }
643}
644
645impl TryFrom<ManifestAddress> for ManifestResourceAddress {
646 type Error = ParseResourceAddressError;
647
648 fn try_from(value: ManifestAddress) -> Result<Self, Self::Error> {
649 Ok(match value {
650 ManifestAddress::Static(value) => Self::Static(value.try_into()?),
651 ManifestAddress::Named(value) => Self::Named(value),
652 })
653 }
654}
655
656pub trait ResolvableStaticManifestResourceAddress: Sized {
662 fn resolve_static(self) -> ResourceAddress;
663}
664
665impl<A, E> ResolvableStaticManifestResourceAddress for A
666where
667 A: TryInto<ManifestResourceAddress, Error = E>,
668 E: Debug,
669{
670 fn resolve_static(self) -> ResourceAddress {
671 let address = self
672 .try_into()
673 .expect("Address was not a valid ManifestResourceAddress");
674 match address {
675 ManifestResourceAddress::Static(address) => address,
676 ManifestResourceAddress::Named(_) => {
677 panic!("This address needs to be a static/fixed address")
678 }
679 }
680 }
681}