iota_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!($ty),"`].")]
26 $vis const LENGTH: usize = $length;
27
28 #[doc = concat!("Creates a new [`", stringify!($ty),"`].")]
29 $vis fn new(bytes: [u8; $name::LENGTH]) -> Self {
30 Self::from(bytes)
31 }
32
33 #[doc = concat!("Creates a null [`", stringify!($ty),"`].")]
34 pub fn null() -> Self {
35 Self::from([0u8; $name::LENGTH])
36 }
37
38 #[doc = concat!("Checks if the [`", stringify!($ty),"`] 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::from(prefix_hex::decode::<[u8; Self::LENGTH]>(s).map_err($crate::block::Error::Hex)?))
49 }
50 }
51
52 impl core::fmt::Display for $name {
53 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
54 write!(f, "{}", prefix_hex::encode(self.0))
55 }
56 }
57
58 impl core::fmt::Debug for $name {
59 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
60 write!(f, "{}({})", stringify!($name), self)
61 }
62 }
63
64 impl core::ops::Deref for $name {
65 type Target = [u8; $name::LENGTH];
66
67 fn deref(&self) -> &Self::Target {
68 &self.0
69 }
70 }
71 };
72}
73
74#[macro_export]
76#[cfg(feature = "serde")]
77macro_rules! string_serde_impl {
78 ($type:ty) => {
79 impl serde::Serialize for $type {
80 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
81 use alloc::string::ToString;
82
83 s.serialize_str(&self.to_string())
84 }
85 }
86
87 impl<'de> serde::Deserialize<'de> for $type {
88 fn deserialize<D>(deserializer: D) -> Result<$type, D::Error>
89 where
90 D: serde::Deserializer<'de>,
91 {
92 struct StringVisitor;
93
94 impl<'de> serde::de::Visitor<'de> for StringVisitor {
95 type Value = $type;
96
97 fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
98 formatter.write_str("a string representing the value")
99 }
100
101 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
102 where
103 E: serde::de::Error,
104 {
105 let value = core::str::FromStr::from_str(v).map_err(serde::de::Error::custom)?;
106 Ok(value)
107 }
108 }
109
110 deserializer.deserialize_str(StringVisitor)
111 }
112 }
113 };
114}
115
116#[macro_export]
120macro_rules! create_bitflags {
121 ($(#[$meta:meta])* $vis:vis $Name:ident, $TagType:ty, [$(($FlagName:ident, $TypeName:ident),)+]) => {
122 bitflags! {
123 $(#[$meta])*
124 $vis struct $Name: $TagType {
125 $(
126 #[doc = concat!("Signals the presence of a [`", stringify!($TypeName), "`].")]
127 const $FlagName = 1 << $TypeName::KIND;
128 )*
129 }
130 }
131
132 impl $Name {
133 #[allow(dead_code)]
134 $vis const ALL_FLAGS: &'static [$Name] = &[$($Name::$FlagName),*];
136 }
137 };
138}