use crate::DiagramTarget;
use core::{any::type_name, marker::PhantomData};
use pipecircuit::{
BindingDescription, DescribeBindings, DescribeRoster, PipeDescription, PipeRoster, Switchboard,
};
mod html;
mod render;
pub struct ProgramDiagram<Roster: DescribeRoster> {
board: &'static str,
pipes: Vec<PipeDescription>,
roster: PhantomData<fn() -> Roster>,
}
impl<Roster: DescribeRoster> ProgramDiagram<Roster> {
pub fn for_board<Board: Switchboard>() -> Self
where
Roster: for<'a> PipeRoster<From<'a> = Board::From<'a>, To<'a> = Board::To<'a>>,
{
Self {
board: type_name::<Board>(),
pipes: Roster::describe_pipes().collect(),
roster: PhantomData,
}
}
pub fn board(&self) -> &'static str {
self.board
}
pub fn pipes(&self) -> &[PipeDescription] {
&self.pipes
}
pub fn render_html(&self) -> String {
html::render(self.board, &self.pipes, None)
}
pub fn render(&self, target: DiagramTarget) -> String {
render::render(self.board, &self.pipes, None, target)
}
pub fn installed<Bindings: DescribeBindings<Roster = Roster>>(
&self,
bindings: &Bindings,
) -> InstallationDiagram {
InstallationDiagram {
board: self.board,
pipes: self.pipes.clone(),
bindings: bindings.describe_bindings().collect(),
}
}
}
pub struct InstallationDiagram {
board: &'static str,
pipes: Vec<PipeDescription>,
bindings: Vec<BindingDescription>,
}
impl InstallationDiagram {
pub fn bindings(&self) -> &[BindingDescription] {
&self.bindings
}
pub fn render_html(&self) -> String {
html::render(self.board, &self.pipes, Some(&self.bindings))
}
pub fn render(&self, target: DiagramTarget) -> String {
render::render(self.board, &self.pipes, Some(&self.bindings), target)
}
}
#[cfg(test)]
mod tests;