use cadmpeg_ir::ids::{
Identity, IdentityComponent, IdentityKey, IdentityNamespace, StaticIdentityComponent,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct IdFormat {
proof: StaticIdentityComponent,
}
impl IdFormat {
#[must_use]
pub const fn from_literal(value: &'static str) -> Option<Self> {
match StaticIdentityComponent::new(value) {
Some(proof) => Some(Self { proof }),
None => None,
}
}
#[must_use]
pub(crate) fn brep_namespace(self, kind: &IdentityComponent) -> IdentityNamespace {
let format = IdentityComponent::from_static(self.proof);
let scope = cadmpeg_ir::identity_component!("brep");
IdentityNamespace::from_components(&format, &scope, kind)
}
#[must_use]
pub(crate) fn brep_identity(
self,
kind: &IdentityComponent,
key: impl Into<IdentityKey>,
) -> Identity {
Identity::compose(&self.brep_namespace(kind), key)
}
pub(crate) fn try_brep_identity(
self,
ctx: &cadmpeg_core::decode::DecodeContext<'_>,
kind: &IdentityComponent,
record_index: usize,
) -> Result<Identity, cadmpeg_core::CodecError> {
let format = IdentityComponent::from_static(self.proof);
let text = ctx.format_retained(
format_args!("{}:brep:{}#{record_index}", format.as_str(), kind.as_str()),
"ASM unknown record identity",
)?;
Identity::new(text).map_err(cadmpeg_core::CodecError::malformed)
}
}
impl std::fmt::Display for IdFormat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(IdentityComponent::from_static(self.proof).as_str())
}
}
#[macro_export]
macro_rules! asm_format {
($value:literal) => {{
const STATIC_FORMAT: $crate::ids::IdFormat =
match $crate::ids::IdFormat::from_literal($value) {
Some(format) => format,
None => panic!("ASM identity format literal has invalid grammar"),
};
STATIC_FORMAT
}};
}
macro_rules! brep_id {
($format:expr, $type:ty, $kind:literal, $key:expr) => {{
<$type>::compose(
&$format.brep_namespace(&cadmpeg_ir::identity_component!($kind)),
$key,
)
}};
}
pub(crate) use brep_id;
macro_rules! brep_key {
($value:literal, $($rest:tt)+) => {{
cadmpeg_ir::identity_key!($value).then($crate::ids::brep_key!($($rest)+))
}};
($value:literal) => {
cadmpeg_ir::identity_key!($value)
};
($value:expr, $($rest:tt)+) => {{
cadmpeg_ir::ids::IdentityKey::from($value).then($crate::ids::brep_key!($($rest)+))
}};
($value:expr) => {
cadmpeg_ir::ids::IdentityKey::from($value)
};
}
pub(crate) use brep_key;