iota_stardust_types/block/
macro.rs1#[macro_export]
6macro_rules! impl_id {
7 ($vis:vis $name:ident, $length:literal, $doc:literal) => {
8 #[doc = $doc]
9 #[derive(
10 Clone,
11 Copy,
12 Eq,
13 Hash,
14 PartialEq,
15 Ord,
16 PartialOrd,
17 derive_more::From,
18 derive_more::AsRef,
19 packable::Packable,
20 )]
21 #[as_ref(forward)]
22 $vis struct $name([u8; $name::LENGTH]);
23
24 impl $name {
25 #[doc = concat!("The length of a [`", stringify!($name),"`].")]
26 $vis const LENGTH: usize = $length;
27
28 #[doc = concat!("Creates a new [`", stringify!($name),"`].")]
29 $vis fn new(bytes: [u8; $name::LENGTH]) -> Self {
30 Self::from(bytes)
31 }
32
33 #[doc = concat!("Creates a null [`", stringify!($name),"`].")]
34 pub fn null() -> Self {
35 Self::from([0u8; $name::LENGTH])
36 }
37
38 #[doc = concat!("Checks if the [`", stringify!($name),"`] is null.")]
39 pub fn is_null(&self) -> bool {
40 self.0.iter().all(|&b| b == 0)
41 }
42 }
43
44 impl core::str::FromStr for $name {
45 type Err = $crate::block::Error;
46
47 fn from_str(s: &str) -> Result<Self, Self::Err> {
48 Ok($name::new(prefix_hex::decode(s).map_err($crate::block::Error::Hex)?))
49 }
50 }
51
52 impl TryFrom<&alloc::string::String> for $name {
53 type Error = $crate::block::Error;
54
55 fn try_from(s: &alloc::string::String) -> Result<Self, Self::Error> {
56 core::str::FromStr::from_str(s.as_str())
57 }
58 }
59
60 impl TryFrom<&str> for $name {
61 type Error = $crate::block::Error;
62
63 fn try_from(s: &str) -> Result<Self, Self::Error> {
64 core::str::FromStr::from_str(s)
65 }
66 }
67
68 impl $crate::block::ConvertTo<$name> for &alloc::string::String {
69 fn convert(self) -> Result<$name, $crate::block::Error> {
70 self.try_into()
71 }
72 }
73
74 impl $crate::block::ConvertTo<$name> for &str {
75 fn convert(self) -> Result<$name, $crate::block::Error> {
76 self.try_into()
77 }
78 }
79
80 impl core::fmt::Display for $name {
81 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
82 write!(f, "{}", prefix_hex::encode(self.0))
83 }
84 }
85
86 impl core::fmt::Debug for $name {
87 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
88 write!(f, "{}({})", stringify!($name), self)
89 }
90 }
91
92 impl core::ops::Deref for $name {
93 type Target = [u8; $name::LENGTH];
94
95 fn deref(&self) -> &Self::Target {
96 &self.0
97 }
98 }
99 };
100}
101
102#[macro_export]
104#[cfg(feature = "serde")]
105macro_rules! string_serde_impl {
106 ($type:ty) => {
107 impl serde::Serialize for $type {
108 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
109 use alloc::string::ToString;
110
111 s.serialize_str(&self.to_string())
112 }
113 }
114
115 impl<'de> serde::Deserialize<'de> for $type {
116 fn deserialize<D>(deserializer: D) -> Result<$type, D::Error>
117 where
118 D: serde::Deserializer<'de>,
119 {
120 struct StringVisitor;
121
122 impl<'de> serde::de::Visitor<'de> for StringVisitor {
123 type Value = $type;
124
125 fn expecting(
126 &self,
127 formatter: &mut core::fmt::Formatter<'_>,
128 ) -> core::fmt::Result {
129 formatter.write_str("a string representing the value")
130 }
131
132 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
133 where
134 E: serde::de::Error,
135 {
136 let value =
137 core::str::FromStr::from_str(v).map_err(serde::de::Error::custom)?;
138 Ok(value)
139 }
140 }
141
142 deserializer.deserialize_str(StringVisitor)
143 }
144 }
145 };
146}
147
148#[macro_export]
155macro_rules! create_bitflags {
156 ($(#[$meta:meta])* $vis:vis $Name:ident, $TagType:ty, [$(($FlagName:ident, $TypeName:ident),)+]) => {
157 bitflags! {
158 $(#[$meta])*
159 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
160 $vis struct $Name: $TagType {
161 $(
162 #[doc = concat!("Signals the presence of a [`", stringify!($TypeName), "`].")]
163 const $FlagName = 1 << $TypeName::KIND;
164 )*
165 }
166 }
167
168 impl $Name {
169 #[allow(dead_code)]
170 $vis const ALL_FLAGS: &'static [$Name] = &[$($Name::$FlagName),*];
172 }
173 };
174}