#[macro_export]
macro_rules! subjects {
(stem = $stem:expr; $( $(#[$note:meta])* $name:ident = $declared:literal ),+ $(,)?) => {
$(
$(#[$note])*
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct $name;
impl $crate::identity::Subject for $name {
const NAME: &'static str = $declared;
const STEM: &'static str = $stem;
}
)+
const _: () = ::core::assert!(
$crate::identity::names_are_separating(&[$($declared),+]),
"a subject name outside the derive-key grammar, or one two subjects declare",
);
};
}
#[must_use]
pub(crate) const fn static_bytes<const N: usize>(text: &str) -> [u8; N] {
assert!(
text.len() == N,
"a declared width that is not the rendering's own length"
);
let mut rendered = [0u8; N];
let mut source = text.as_bytes();
let mut sink: &mut [u8] = &mut rendered;
while let Some((seat, open)) = sink.split_first_mut() {
let Some((byte, remaining)) = source.split_first() else {
break;
};
*seat = *byte;
sink = open;
source = remaining;
}
rendered
}
macro_rules! human_projection {
($text:literal) => {{
const RENDERED: [u8; $text.len()] = $crate::identity::static_bytes($text);
$crate::identity::HumanProjection::proven(RENDERED)
}};
}
pub(crate) use human_projection;