use std::any::Any;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum OpKind {
Regular,
Generator,
}
pub struct OpEntry {
pub name: &'static str,
pub module_path: &'static str,
pub kind: OpKind,
pub op_fn: fn(&serde_json::Value) -> serde_json::Value,
}
impl OpEntry {
pub const fn new_op(
name: &'static str,
module_path: &'static str,
op_fn: fn(&serde_json::Value) -> serde_json::Value,
) -> Self {
OpEntry {
name,
module_path,
kind: OpKind::Regular,
op_fn,
}
}
pub const fn new_gen(
name: &'static str,
module_path: &'static str,
op_fn: fn(&serde_json::Value) -> serde_json::Value,
) -> Self {
OpEntry {
name,
module_path,
kind: OpKind::Generator,
op_fn,
}
}
pub fn qualified_name(&self) -> String {
match self.module_path.find("::") {
Some(idx) => {
let stripped = &self.module_path[idx + 2..];
if stripped.is_empty() {
self.name.to_string()
} else {
format!("{}::{}", stripped, self.name)
}
}
None => self.name.to_string(),
}
}
}
inventory::collect!(OpEntry);
pub struct ResourceEntry {
pub name: &'static str,
pub factory: fn(&serde_json::Value) -> Box<dyn Any + Send + Sync>,
}
impl ResourceEntry {
pub const fn new(
name: &'static str,
factory: fn(&serde_json::Value) -> Box<dyn Any + Send + Sync>,
) -> Self {
ResourceEntry { name, factory }
}
}
inventory::collect!(ResourceEntry);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn qualified_name_strips_crate_prefix() {
let e = OpEntry::new_op("double", "my_crate::math", |_| serde_json::Value::Null);
assert_eq!(e.qualified_name(), "math::double");
}
#[test]
fn qualified_name_handles_crate_root() {
let e = OpEntry::new_op("double", "my_crate", |_| serde_json::Value::Null);
assert_eq!(e.qualified_name(), "double");
}
#[test]
fn qualified_name_deep_module() {
let e = OpEntry::new_op("classify", "my_crate::a::b::c", |_| serde_json::Value::Null);
assert_eq!(e.qualified_name(), "a::b::c::classify");
}
}