1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use use_incidence::IncidenceStructure;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct GeometricConfiguration {
9 point_count: usize,
10 line_count: usize,
11 incidence_count: usize,
12}
13
14impl GeometricConfiguration {
15 #[must_use]
17 pub const fn new(
18 point_count: usize,
19 line_count: usize,
20 incidence_count: usize,
21 ) -> Option<Self> {
22 if point_count > 0 && line_count > 0 {
23 Some(Self {
24 point_count,
25 line_count,
26 incidence_count,
27 })
28 } else {
29 None
30 }
31 }
32
33 #[must_use]
35 pub const fn point_count(self) -> usize {
36 self.point_count
37 }
38
39 #[must_use]
41 pub const fn line_count(self) -> usize {
42 self.line_count
43 }
44
45 #[must_use]
47 pub const fn incidence_count(self) -> usize {
48 self.incidence_count
49 }
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54pub struct DoubleSix {
55 first: [usize; 6],
56 second: [usize; 6],
57}
58
59impl DoubleSix {
60 #[must_use]
62 pub const fn new(first: [usize; 6], second: [usize; 6]) -> Self {
63 Self { first, second }
64 }
65
66 #[must_use]
68 pub const fn standard() -> Self {
69 Self::new([0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11])
70 }
71
72 #[must_use]
74 pub const fn first(self) -> [usize; 6] {
75 self.first
76 }
77
78 #[must_use]
80 pub const fn second(self) -> [usize; 6] {
81 self.second
82 }
83
84 #[must_use]
86 pub const fn pair_count(self) -> usize {
87 6
88 }
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
93pub struct SchlafliDoubleSix {
94 arrangement: DoubleSix,
95 configuration: GeometricConfiguration,
96}
97
98impl SchlafliDoubleSix {
99 #[must_use]
101 pub const fn new() -> Self {
102 Self {
103 arrangement: DoubleSix::standard(),
104 configuration: GeometricConfiguration {
105 point_count: 12,
106 line_count: 30,
107 incidence_count: 60,
108 },
109 }
110 }
111
112 #[must_use]
114 pub const fn arrangement(self) -> DoubleSix {
115 self.arrangement
116 }
117
118 #[must_use]
120 pub const fn configuration(self) -> GeometricConfiguration {
121 self.configuration
122 }
123
124 #[must_use]
126 pub fn incidence_structure(self) -> IncidenceStructure {
127 IncidenceStructure::new(
128 self.configuration.point_count(),
129 self.configuration.line_count(),
130 Vec::new(),
131 )
132 .expect("standard double-six counts are positive")
133 }
134}
135
136impl Default for SchlafliDoubleSix {
137 fn default() -> Self {
138 Self::new()
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::{DoubleSix, GeometricConfiguration, SchlafliDoubleSix};
145
146 #[test]
147 fn stores_schlafli_double_six_metadata() {
148 let double_six = SchlafliDoubleSix::new();
149 let structure = double_six.incidence_structure();
150
151 assert_eq!(double_six.arrangement().pair_count(), 6);
152 assert_eq!(double_six.configuration().point_count(), 12);
153 assert_eq!(structure.line_count(), 30);
154 assert_eq!(DoubleSix::standard().first(), [0, 1, 2, 3, 4, 5]);
155 assert_eq!(GeometricConfiguration::new(0, 1, 0), None);
156 }
157}