#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Channel {
Send,
Bg,
Emit,
Ask,
}
pub type Name = fn() -> &'static str;
pub fn name<T: ?Sized>() -> &'static str {
super::short_type_name::<T>()
}
#[derive(Clone, Copy)]
pub struct Edge {
pub channel: Channel,
pub target: Name,
pub looping: bool,
}
#[derive(Clone, Copy)]
pub struct Handles {
pub message: Name,
pub edges: Option<&'static [Edge]>,
pub declared: Option<Declared>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Declared {
pub file: &'static str,
pub line: u32,
pub column: u32,
pub crate_dir: &'static str,
}
#[macro_export]
macro_rules! declared {
() => {
$crate::actor::shape::Declared {
file: ::core::file!(),
line: ::core::line!(),
column: ::core::column!(),
crate_dir: ::core::env!("CARGO_MANIFEST_DIR"),
}
};
}
impl Declared {
pub fn path(&self) -> Option<std::path::PathBuf> {
let file = std::path::Path::new(self.file);
if file.is_absolute() {
return file.exists().then(|| file.to_path_buf());
}
std::path::Path::new(self.crate_dir)
.ancestors()
.map(|dir| dir.join(file))
.find(|path| path.exists())
}
}
#[derive(Clone, Copy)]
pub struct Shape {
pub handles: &'static [Handles],
pub publishes: &'static [Name],
pub subscribes: &'static [Name],
pub declared: Option<Declared>,
}
impl Shape {
pub const UNKNOWN: Shape = Shape {
handles: &[],
publishes: &[],
subscribes: &[],
declared: None,
};
}
impl std::fmt::Debug for Shape {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Shape")
.field(
"handles",
&self.handles.iter().map(|h| (h.message)()).collect::<Vec<_>>(),
)
.field(
"publishes",
&self.publishes.iter().map(|n| n()).collect::<Vec<_>>(),
)
.field(
"subscribes",
&self.subscribes.iter().map(|n| n()).collect::<Vec<_>>(),
)
.field("declared", &self.declared)
.finish()
}
}