ab_core_primitives/
address.rs1use crate::shard::ShardIndex;
4use ab_io_type::metadata::IoTypeMetadataKind;
5use ab_io_type::trivial_type::TrivialType;
6use core::cmp::Ordering;
7use core::mem::MaybeUninit;
8use core::{fmt, ptr};
9
10#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
14#[repr(C)]
15pub struct Address(u64, u64);
16
17unsafe impl TrivialType for Address {
18 const METADATA: &[u8] = &[IoTypeMetadataKind::Address as u8];
19}
20
21const _: () = {
23 let (type_details, _metadata) = IoTypeMetadataKind::type_details(Address::METADATA)
24 .expect("Statically correct metadata; qed");
25 assert!(size_of::<Address>() == type_details.recommended_capacity as usize);
26 assert!(align_of::<Address>() == type_details.alignment.get() as usize);
27};
28
29impl fmt::Debug for Address {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 f.debug_tuple("Address").field(&self.as_u128()).finish()
32 }
33}
34
35impl fmt::Display for Address {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 self.as_u128().fmt(f)
39 }
40}
41
42impl PartialEq<&Address> for Address {
43 #[inline(always)]
44 fn eq(&self, other: &&Address) -> bool {
45 self.0 == other.0
46 }
47}
48
49impl PartialEq<Address> for &Address {
50 #[inline(always)]
51 fn eq(&self, other: &Address) -> bool {
52 self.0 == other.0
53 }
54}
55
56impl Ord for Address {
57 #[inline(always)]
58 fn cmp(&self, other: &Address) -> Ordering {
59 self.as_u128().cmp(&other.as_u128())
60 }
61}
62
63impl PartialOrd for Address {
64 #[inline(always)]
65 fn partial_cmp(&self, other: &Address) -> Option<Ordering> {
66 Some(self.cmp(other))
67 }
68}
69
70impl From<u128> for Address {
71 #[inline(always)]
72 fn from(value: u128) -> Self {
73 Self::new(value)
74 }
75}
76
77impl From<Address> for u128 {
78 #[inline(always)]
79 fn from(value: Address) -> Self {
80 value.as_u128()
81 }
82}
83
84impl Address {
87 pub const NULL: Self = Self::new(0);
90 pub const SYSTEM_CODE: Self = Self::new(1);
92 pub const SYSTEM_BLOCK: Self = Self::new(2);
94 pub const SYSTEM_STATE: Self = Self::new(3);
96 pub const SYSTEM_NATIVE_TOKEN: Self = Self::new(4);
98 pub const SYSTEM_SIMPLE_WALLET_BASE: Self = Self::new(10);
100
101 #[inline(always)]
103 const fn new(n: u128) -> Self {
104 let mut result = MaybeUninit::<Self>::uninit();
105 unsafe {
107 result.as_mut_ptr().cast::<u128>().write_unaligned(n);
108 result.assume_init()
109 }
110 }
111
112 #[inline(always)]
114 const fn as_u128(self) -> u128 {
115 unsafe { ptr::from_ref(&self).cast::<u128>().read_unaligned() }
117 }
118
119 #[inline(always)]
121 pub const fn system_address_allocator(shard_index: ShardIndex) -> Self {
122 Self::new(shard_index.as_u32() as u128 * ShardIndex::MAX_ADDRESSES_PER_SHARD.get())
126 }
127}