pub trait Describable {
fn describe(&self) -> String;
fn short_name(&self) -> &str;
fn category(&self) -> &str;
}
impl Describable for crate::graph::hex_node::HexNode {
fn describe(&self) -> String {
format!(
"{} ({:?} in {:?} layer)",
self.type_name, self.role, self.layer
)
}
fn short_name(&self) -> &str {
&self.type_name
}
fn category(&self) -> &str {
match self.layer {
crate::graph::layer::Layer::Domain => "Domain Model",
crate::graph::layer::Layer::Port => "Interface",
crate::graph::layer::Layer::Adapter => "Implementation",
crate::graph::layer::Layer::Application => "Use Case",
crate::graph::layer::Layer::Infrastructure => "Infrastructure",
crate::graph::layer::Layer::Unknown => "Unknown",
}
}
}
impl Describable for crate::graph::hex_graph::HexGraph {
fn describe(&self) -> String {
format!(
"HexGraph with {} nodes and {} edges",
self.node_count(),
self.edge_count()
)
}
fn short_name(&self) -> &str {
"HexGraph"
}
fn category(&self) -> &str {
"Architecture Graph"
}
}
impl Describable for std::sync::Arc<crate::graph::hex_graph::HexGraph> {
fn describe(&self) -> String {
(**self).describe()
}
fn short_name(&self) -> &str {
(**self).short_name()
}
fn category(&self) -> &str {
(**self).category()
}
}
pub trait PrettyPrint {
fn pretty_print(&self);
}
impl PrettyPrint for std::sync::Arc<crate::graph::hex_graph::HexGraph> {
fn pretty_print(&self) {
println!("{}", self.describe());
}
}
pub trait ArcGraphExt {
fn nodes_by_layer(
&self,
layer: crate::graph::layer::Layer,
) -> Vec<&crate::graph::hex_node::HexNode>;
fn nodes_by_role(&self, role: crate::graph::role::Role) -> Vec<&crate::graph::hex_node::HexNode>;
}
impl ArcGraphExt for std::sync::Arc<crate::graph::hex_graph::HexGraph> {
fn nodes_by_layer(
&self,
layer: crate::graph::layer::Layer,
) -> Vec<&crate::graph::hex_node::HexNode> {
(**self).nodes_by_layer(layer)
}
fn nodes_by_role(&self, role: crate::graph::role::Role) -> Vec<&crate::graph::hex_node::HexNode> {
(**self).nodes_by_role(role)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_node_describable() {
let node = crate::graph::hex_node::HexNode::new(
crate::graph::node_id::NodeId::from_name("User"),
crate::graph::layer::Layer::Domain,
crate::graph::role::Role::Entity,
"User",
"domain::user",
);
assert_eq!(node.short_name(), "User");
assert_eq!(node.category(), "Domain Model");
assert!(node.describe().contains("Entity"));
}
#[test]
fn test_graph_describable() {
let graph = crate::graph::builder::GraphBuilder::new().build();
assert_eq!(graph.short_name(), "HexGraph");
assert_eq!(graph.category(), "Architecture Graph");
assert!(graph.describe().contains("0 nodes"));
}
#[test]
fn test_arc_graph_ext() {
let graph = std::sync::Arc::new(
crate::graph::builder::GraphBuilder::new()
.add_node(crate::graph::hex_node::HexNode::new(
crate::graph::node_id::NodeId::from_name("Test"),
crate::graph::layer::Layer::Domain,
crate::graph::role::Role::Entity,
"Test",
"test",
))
.build(),
);
let domain_nodes = graph.nodes_by_layer(crate::graph::layer::Layer::Domain);
assert_eq!(domain_nodes.len(), 1);
let entities = graph.nodes_by_role(crate::graph::role::Role::Entity);
assert_eq!(entities.len(), 1);
}
}