lib.rs
  1  #[macro_export]
  2  macro_rules! array_type_define {
  3      (
  4          $(#[$outer:meta])*
  5          $v:vis struct $name:tt[$n:literal];
  6      ) => {
  7  
  8          $(#[$outer])*
  9          #[derive(PartialOrd, Ord, PartialEq, Eq)]
 10          $v struct $name([u8; $n]);
 11  
 12          impl $name {
 13  
 14              pub const LEN: usize = $n;
 15              pub const MIN: Self = Self([0u8; $n]);
 16              pub const MAX: Self = Self([0xffu8; $n]);
 17  
 18              pub fn as_slice(&self) -> &[u8] {
 19                  self.0.as_slice()
 20              }
 21  
 22              pub fn from_bytes(bytes: [u8; $n]) -> Self {
 23                  Self(bytes)
 24              }
 25  
 26              pub fn to_bytes(self) -> [u8; $n] {
 27                  self.0
 28              }
 29          }
 30      }
 31  }
 32  
 33  #[macro_export]
 34  macro_rules! array_type_impl_zero_default {
 35      ($name:tt) => {
 36          impl Default for $name {
 37              fn default() -> Self {
 38                  Self([0; Self::LEN])
 39              }
 40          }
 41      };
 42  }
 43  
 44  #[macro_export]
 45  macro_rules! array_type_impl_debug_as_display {
 46      ($name:tt) => {
 47          impl std::fmt::Debug for $name {
 48              fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 49                  <Self as std::fmt::Display>::fmt(self, f)
 50              }
 51          }
 52      };
 53  }
 54  
 55  #[macro_export]
 56  macro_rules! array_type_impl_serde {
 57      (
 58          $name:tt
 59      ) => {
 60          impl ::serde::Serialize for $name {
 61              fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
 62              where
 63                  S: ::serde::Serializer,
 64              {
 65                  if s.is_human_readable() {
 66                      s.serialize_str(&self.to_string())
 67                  } else {
 68                      s.serialize_bytes(&self.0)
 69                  }
 70              }
 71          }
 72  
 73          impl<'de> ::serde::de::Deserialize<'de> for $name {
 74              fn deserialize<D>(d: D) -> Result<Self, D::Error>
 75              where
 76                  D: ::serde::Deserializer<'de>,
 77              {
 78                  if d.is_human_readable() {
 79                      let str = <String>::deserialize(d)?;
 80                      <Self as std::str::FromStr>::from_str(&str).map_err(|e| {
 81                          ::serde::de::Error::custom(format!("Deserialization error: {e:#}"))
 82                      })
 83                  } else {
 84                      let bytes = <serde_bytes::ByteArray<{ $name::LEN }>>::deserialize(d)?;
 85                      Ok(Self(bytes.into_array()))
 86                  }
 87              }
 88          }
 89      };
 90  }
 91  
 92  #[macro_export]
 93  macro_rules! array_type_impl_base32_str {
 94      (
 95          $name:tt
 96      ) => {
 97          impl std::fmt::Display for $name {
 98              fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 99                  data_encoding::BASE32_NOPAD.encode_write(self.as_slice(), f)
100              }
101          }
102  
103          impl std::str::FromStr for $name {
104              type Err = data_encoding::DecodeError;
105  
106              fn from_str(s: &str) -> Result<$name, Self::Err> {
107                  let v = data_encoding::BASE32_NOPAD.decode(s.as_bytes())?;
108                  let a = v.try_into().map_err(|_| data_encoding::DecodeError {
109                      position: 0,
110                      kind: data_encoding::DecodeKind::Length,
111                  })?;
112                  Ok(Self(a))
113              }
114          }
115      };
116  }
117  
118  #[macro_export]
119  macro_rules! array_type_impl_base64_str {
120      (
121          $name:tt
122      ) => {
123          impl std::fmt::Display for $name {
124              fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125                  data_encoding::BASE64_NOPAD.encode_write(self.as_slice(), f)
126              }
127          }
128  
129          impl std::str::FromStr for $name {
130              type Err = data_encoding::DecodeError;
131  
132              fn from_str(s: &str) -> Result<$name, Self::Err> {
133                  let v = data_encoding::BASE64_NOPAD.decode(s.as_bytes())?;
134                  let a = v.try_into().map_err(|_| data_encoding::DecodeError {
135                      position: 0,
136                      kind: data_encoding::DecodeKind::Length,
137                  })?;
138                  Ok(Self(a))
139              }
140          }
141      };
142  }