#![forbid(unsafe_code)]
use rustc_hash::{FxHashMap, FxHashSet};
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct ExternDialect {
pub name: &'static str,
pub version: &'static str,
pub crate_repo: &'static str,
}
impl ExternDialect {
#[must_use]
pub const fn new(name: &'static str, version: &'static str, crate_repo: &'static str) -> Self {
Self {
name,
version,
crate_repo,
}
}
}
inventory::collect!(ExternDialect);
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct ExternOp {
pub dialect: &'static str,
pub op_id: &'static str,
}
impl ExternOp {
#[must_use]
pub const fn new(dialect: &'static str, op_id: &'static str) -> Self {
Self { dialect, op_id }
}
}
inventory::collect!(ExternOp);
#[must_use]
pub fn dialects() -> Vec<&'static ExternDialect> {
let iter = inventory::iter::<ExternDialect>();
let (lo, hi) = iter.size_hint();
let mut out = Vec::with_capacity(hi.unwrap_or(lo));
out.extend(iter);
out
}
#[must_use]
pub fn ops_in_dialect(dialect: &str) -> Vec<&'static ExternOp> {
let iter = inventory::iter::<ExternOp>().filter(|op| op.dialect == dialect);
let (lo, hi) = iter.size_hint();
let mut out = Vec::with_capacity(hi.unwrap_or(lo));
out.extend(iter);
out
}
#[must_use]
pub fn all_ops() -> Vec<&'static ExternOp> {
let iter = inventory::iter::<ExternOp>();
let (lo, hi) = iter.size_hint();
let mut out = Vec::with_capacity(hi.unwrap_or(lo));
out.extend(iter);
out
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum ExternVerifyError {
#[error("duplicate dialect name `{name}`: {count} entries registered. Fix: pick a unique crates.io name for each community pack.")]
DuplicateDialect {
name: &'static str,
count: usize,
},
#[error("dialect name `{name}` does not start with `vyre-libs-`. Fix: rename the pack crate and its ExternDialect::name to begin with `vyre-libs-`.")]
MalformedDialectName {
name: &'static str,
},
#[error("orphan op `{op_id}` references dialect `{dialect}`, which is not registered. Fix: make sure the dialect's crate registers an `ExternDialect` entry with this name.")]
OrphanOp {
dialect: &'static str,
op_id: &'static str,
},
#[error("op registered with empty op_id under dialect `{dialect}`. Fix: every op must carry a fully-qualified id like `<dialect>::<op_name>`.")]
EmptyOpId {
dialect: &'static str,
},
}
pub fn verify() -> Result<(), Vec<ExternVerifyError>> {
let mut errors = Vec::new();
let mut counts: FxHashMap<&'static str, usize> = FxHashMap::default();
let mut known: FxHashSet<&'static str> = FxHashSet::default();
for dialect in inventory::iter::<ExternDialect>() {
*counts.entry(dialect.name).or_insert(0) += 1;
known.insert(dialect.name);
if !dialect.name.starts_with("vyre-libs-") {
errors.push(ExternVerifyError::MalformedDialectName { name: dialect.name });
}
}
for (name, count) in counts {
if count > 1 {
errors.push(ExternVerifyError::DuplicateDialect { name, count });
}
}
for op in inventory::iter::<ExternOp>() {
if op.op_id.is_empty() {
errors.push(ExternVerifyError::EmptyOpId {
dialect: op.dialect,
});
}
if !known.contains(op.dialect) {
errors.push(ExternVerifyError::OrphanOp {
dialect: op.dialect,
op_id: op.op_id,
});
}
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn extern_dialect_construction() {
let d = ExternDialect::new("vyre-libs-quant", "0.1.0", "https://github.com/example");
assert_eq!(d.name, "vyre-libs-quant");
assert_eq!(d.version, "0.1.0");
assert_eq!(d.crate_repo, "https://github.com/example");
}
#[test]
fn extern_op_construction() {
let op = ExternOp::new("vyre-libs-quant", "vyre-libs-quant::int8::matmul");
assert_eq!(op.dialect, "vyre-libs-quant");
assert_eq!(op.op_id, "vyre-libs-quant::int8::matmul");
}
#[test]
fn duplicate_dialect_error_display() {
let err = ExternVerifyError::DuplicateDialect {
name: "vyre-libs-x",
count: 3,
};
let msg = err.to_string();
assert!(msg.contains("vyre-libs-x"));
assert!(msg.contains("3"));
}
#[test]
fn malformed_name_error_display() {
let err = ExternVerifyError::MalformedDialectName { name: "bad-name" };
let msg = err.to_string();
assert!(msg.contains("bad-name"));
assert!(msg.contains("vyre-libs-"));
}
#[test]
fn orphan_op_error_display() {
let err = ExternVerifyError::OrphanOp {
dialect: "missing-dialect",
op_id: "missing::op",
};
assert!(err.to_string().contains("orphan"));
}
#[test]
fn empty_op_id_error_display() {
let err = ExternVerifyError::EmptyOpId {
dialect: "vyre-libs-x",
};
assert!(err.to_string().contains("empty"));
}
#[test]
fn verify_empty_registry_succeeds() {
let result = verify();
if let Err(errors) = &result {
for e in errors {
let _ = e.to_string();
}
}
}
}