#[doc(hidden)]
#[macro_export]
macro_rules! opaque {
() => {};
(
$(#[$($struct_meta:meta)*])*
$struct_vis:vis
struct $t:ident ($inner_vis:vis [u8; $l:expr]);
$($rest:tt)*
) => {
$(#[$($struct_meta)*])*
#[derive(
$crate::Encode,
$crate::Decode,
$crate::MaxEncodedLen,
Copy,
Clone,
Eq,
PartialEq,
Ord,
PartialOrd,
Hash,
)]
#[repr(transparent)]
$struct_vis struct $t($inner_vis [u8; $l]);
impl scale::ConstEncodedLen for $t {}
impl Default for $t {
fn default() -> Self {
Self([0; $l])
}
}
impl core::ops::Deref for $t {
type Target = [u8; $l];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl core::ops::DerefMut for $t {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl From<[u8; $l]> for $t {
fn from(value: [u8; $l]) -> Self {
Self(value)
}
}
impl AsRef<[u8; $l]> for $t {
fn as_ref(&self) -> &[u8; $l] {
&self.0
}
}
impl AsMut<[u8; $l]> for $t {
fn as_mut(&mut self) -> &mut [u8; $l] {
&mut self.0
}
}
impl AsMut<[u8]> for $t {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.0[..]
}
}
impl core::fmt::Debug for $t {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
if self.iter().all(|&x| (32..=127).contains(&x) || x == 0) {
let i = self.0.iter().position(|x| *x == 0).unwrap_or($l);
if let Ok(s) = core::str::from_utf8(&self.0[..i]) {
return f.write_fmt(format_args!("\"{s}\""));
}
}
if self.0.len() > 8 {
f.write_fmt(format_args!(
"0x{}...",
$crate::hex::hex(&self.0[..8]),
))
} else {
f.write_fmt(format_args!("0x{}", $crate::hex::hex(&self.0)))
}
}
}
impl core::fmt::Display for $t {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
if self.iter().all(|&x| (32..=127).contains(&x) || x == 0) {
let i = self.0.iter().position(|x| *x == 0).unwrap_or($l);
if let Ok(s) = core::str::from_utf8(&self.0[..i]) {
return f.write_fmt(format_args!("\"{s}\""));
}
}
if self.0.len() > 8 {
f.write_fmt(format_args!(
"0x{}...",
$crate::hex::hex(&self.0[..8]),
))
} else {
f.write_fmt(format_args!("0x{}", $crate::hex::hex(&self.0)))
}
}
}
impl $t {
pub fn zero() -> Self {
Self([0; $l])
}
pub fn padded(left: &[u8]) -> Self {
let mut i = [0; $l];
i[..left.len().min($l)].copy_from_slice(&left[..left.len().min($l)]);
Self(i)
}
pub const fn len() -> usize {
$l
}
#[allow(clippy::wrong_self_convention)]
pub fn to_vec(&self) -> $crate::Vec<u8> {
self.0.to_vec()
}
pub const LEN: usize = $l;
}
impl From<$t> for [u8; $l] {
fn from(value: $t) -> [u8; $l] {
value.0
}
}
opaque! { $($rest)* }
};
(
$(#[$($struct_meta:meta)*])*
$struct_vis:vis
struct $t:ident ($inner_vis:vis Vec<u8>);
$($rest:tt)*
) => {
$(#[$($struct_meta)*])*
#[derive(
$crate::Encode, $crate::Decode, Default, Clone, Eq, PartialEq, Ord, PartialOrd,
)]
$struct_vis struct $t($inner_vis $crate::Vec<u8>);
impl core::ops::Deref for $t {
type Target = $crate::Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl core::ops::DerefMut for $t {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl From<$crate::Vec<u8>> for $t {
fn from(value: $crate::Vec<u8>) -> Self {
Self(value)
}
}
impl $t {
pub fn new() -> Self {
Self($crate::Vec::new())
}
pub fn take(self) -> $crate::Vec<u8> {
self.0
}
}
impl From<$t> for $crate::Vec<u8> {
fn from(other: $t) -> Self {
other.0
}
}
impl core::fmt::Debug for $t {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
core::fmt::Display::fmt(self, f)
}
}
impl core::fmt::Display for $t {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
let suffix = self.iter().rev().take_while(|&&x| x == 0).count();
let body = &self.0[..self.len() - suffix];
if body.iter().all(|&x| (32..=127).contains(&x)) {
if let Ok(s) = core::str::from_utf8(body) {
return f.write_fmt(format_args!("\"{s}\""));
}
}
if body.len() > 32 {
f.write_fmt(format_args!(
"0x{}...",
$crate::hex::hex(&body[..8]),
))?;
} else {
f.write_fmt(format_args!("0x{}", $crate::hex::hex(body)))?;
}
if suffix != 0 {
f.write_fmt(format_args!("+{suffix}*0"))?;
}
Ok(())
}
}
opaque! { $($rest)* }
};
(
$(#[$($struct_meta:meta)*])*
$struct_vis:vis
struct $t:ident ($inner_vis:vis BoundedVec<u8, { $s:expr }>);
$($rest:tt)*
) => {
$(#[$($struct_meta)*])*
#[derive(
$crate::Encode,
$crate::Decode,
$crate::MaxEncodedLen,
Default,
Clone,
Eq,
PartialEq,
Ord,
PartialOrd,
)]
$struct_vis struct $t($inner_vis $crate::BoundedVec<u8, ConstU32<{ $s as u32 }>>);
impl core::ops::Deref for $t {
type Target = $crate::BoundedVec<u8, ConstU32<{ $s as u32 }>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl core::ops::DerefMut for $t {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl TryFrom<$crate::Vec<u8>> for $t {
type Error = ();
fn try_from(value: $crate::Vec<u8>) -> Result<Self, Self::Error> {
Ok(Self($crate::BoundedVec::try_from(value).map_err(|_| ())?))
}
}
impl From<$crate::BoundedVec<u8, ConstU32<{ $s as u32 }>>> for $t {
fn from(value: $crate::BoundedVec<u8, ConstU32<{ $s as u32 }>>) -> Self {
Self(value)
}
}
impl core::fmt::Debug for $t {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
core::fmt::Display::fmt(self, f)
}
}
impl core::fmt::Display for $t {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
if self.0.len() > 32 {
f.write_fmt(format_args!(
"0x{}...",
$crate::hex::hex(&self.0[..8]),
))
} else {
f.write_fmt(format_args!("0x{}", $crate::hex::hex(&self.0)))
}
}
}
opaque! { $($rest)* }
};
}