Skip to content

Instantly share code, notes, and snippets.

@CertainLach
Last active October 11, 2022 08:54
Show Gist options
  • Save CertainLach/7728025e18699310b2a59a9abb6e8fb5 to your computer and use it in GitHub Desktop.
Save CertainLach/7728025e18699310b2a59a9abb6e8fb5 to your computer and use it in GitHub Desktop.
use core::mem::ManuallyDrop;
use core::str::from_utf8;
const SIZE_LIMIT: usize = 40;
trait Name {
const NAME: [u8; SIZE_LIMIT];
const NAME_LEN: usize;
fn name() -> &'static str {
from_utf8(&Self::NAME[..Self::NAME_LEN]).expect("bad utf-8")
}
}
macro_rules! name {
(new $($tt:tt)*) => {
const NAME: [u8; SIZE_LIMIT] = {
let mut out = [0u8; SIZE_LIMIT];
let mut offset = 0;
name!(@data(out, offset); $($tt)*);
out
};
const NAME_LEN: usize = 0 + name!(@size; $($tt)*);
};
(@size;) => {
0
};
(@size; fixed($expr:expr) $($tt:tt)*) => {
$expr.len() + name!(@size; $($tt)*)
};
(@size; nameof($expr:ty) $($tt:tt)*) => {
<$expr>::NAME_LEN + name!(@size; $($tt)*)
};
(@data($out:ident, $offset:ident);) => {};
(@data($out:ident, $offset:ident); fixed($expr:expr) $($tt:tt)*) => {
{
let data = $expr.as_bytes();
let mut doffset = 0;
while doffset < data.len() {
$out[$offset] = data[doffset];
$offset += 1;
doffset += 1;
}
}
name!(@data($out, $offset); $($tt)*)
};
(@data($out:ident, $offset:ident); nameof($expr:ty) $($tt:tt)*) => {
{
let mut doffset = 0;
while doffset < <$expr>::NAME_LEN {
$out[$offset] = <$expr>::NAME[doffset];
$offset += 1;
doffset += 1;
}
}
name!(@data($out, $offset); $($tt)*)
};
}
impl Name for u8 {
name!(new fixed("uint8"));
}
impl Name for u32 {
name!(new fixed("uint32"));
}
impl<T: Name> Name for Vec<T> {
name!(new nameof(T) fixed("[]"));
}
impl<A: Name, B: Name> Name for (A, B) {
name!(new fixed("(") nameof(A) fixed(",") nameof(B) fixed(")"));
}
fn main() {
dbg!(<Vec<u8>>::name());
dbg!(<Vec<u32>>::name());
dbg!(<(Vec<u32>, (u32, Vec<u8>))>::name());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment