1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub struct CoxeterNode {
7 index: usize,
8}
9
10impl CoxeterNode {
11 #[must_use]
13 pub const fn new(index: usize) -> Self {
14 Self { index }
15 }
16
17 #[must_use]
19 pub const fn index(self) -> usize {
20 self.index
21 }
22}
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub struct CoxeterEdge {
27 start: usize,
28 end: usize,
29 order: Option<usize>,
30}
31
32impl CoxeterEdge {
33 #[must_use]
35 pub const fn new(start: usize, end: usize, order: Option<usize>) -> Option<Self> {
36 if start == end {
37 return None;
38 }
39
40 if let Some(order) = order
41 && order < 3
42 {
43 return None;
44 }
45
46 Some(Self { start, end, order })
47 }
48
49 #[must_use]
51 pub const fn endpoints(self) -> (usize, usize) {
52 (self.start, self.end)
53 }
54
55 #[must_use]
57 pub const fn order(self) -> Option<usize> {
58 self.order
59 }
60}
61
62#[derive(Debug, Clone, PartialEq, Eq)]
64pub struct CoxeterDiagram {
65 nodes: Vec<CoxeterNode>,
66 edges: Vec<CoxeterEdge>,
67}
68
69impl CoxeterDiagram {
70 #[must_use]
72 pub fn new(nodes: Vec<CoxeterNode>, edges: Vec<CoxeterEdge>) -> Option<Self> {
73 if edges.iter().all(|edge| {
74 nodes.iter().any(|node| node.index() == edge.start)
75 && nodes.iter().any(|node| node.index() == edge.end)
76 }) {
77 Some(Self { nodes, edges })
78 } else {
79 None
80 }
81 }
82
83 #[must_use]
85 pub fn nodes(&self) -> &[CoxeterNode] {
86 &self.nodes
87 }
88
89 #[must_use]
91 pub fn edges(&self) -> &[CoxeterEdge] {
92 &self.edges
93 }
94
95 #[must_use]
97 pub fn node_count(&self) -> usize {
98 self.nodes.len()
99 }
100
101 #[must_use]
103 pub fn edge_count(&self) -> usize {
104 self.edges.len()
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use super::{CoxeterDiagram, CoxeterEdge, CoxeterNode};
111
112 #[test]
113 fn validates_coxeter_diagrams() {
114 let nodes = vec![CoxeterNode::new(0), CoxeterNode::new(1)];
115 let edge = CoxeterEdge::new(0, 1, Some(3)).expect("valid edge");
116 let diagram = CoxeterDiagram::new(nodes, vec![edge]).expect("valid diagram");
117
118 assert_eq!(diagram.node_count(), 2);
119 assert_eq!(diagram.edge_count(), 1);
120 assert_eq!(edge.endpoints(), (0, 1));
121 assert_eq!(CoxeterEdge::new(0, 0, None), None);
122 }
123}