Skip to main content

use_duality/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4/// A named dual pair.
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub struct Dual {
7    primal: &'static str,
8    dual: &'static str,
9}
10
11impl Dual {
12    /// Creates a dual pair.
13    #[must_use]
14    pub const fn new(primal: &'static str, dual: &'static str) -> Self {
15        Self { primal, dual }
16    }
17
18    /// Returns the primal name.
19    #[must_use]
20    pub const fn primal(self) -> &'static str {
21        self.primal
22    }
23
24    /// Returns the dual name.
25    #[must_use]
26    pub const fn dual(self) -> &'static str {
27        self.dual
28    }
29}
30
31/// Metadata describing a duality relationship.
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub struct Duality {
34    pair: Dual,
35    involutive: bool,
36}
37
38impl Duality {
39    /// Creates a duality descriptor.
40    #[must_use]
41    pub const fn new(pair: Dual, involutive: bool) -> Self {
42        Self { pair, involutive }
43    }
44
45    /// Returns the dual pair.
46    #[must_use]
47    pub const fn pair(self) -> Dual {
48        self.pair
49    }
50
51    /// Returns whether applying the duality twice returns to the starting family.
52    #[must_use]
53    pub const fn is_involutive(self) -> bool {
54        self.involutive
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::{Dual, Duality};
61
62    #[test]
63    fn stores_duality_metadata() {
64        let pair = Dual::new("cube", "octahedron");
65        let duality = Duality::new(pair, true);
66
67        assert_eq!(duality.pair().primal(), "cube");
68        assert_eq!(duality.pair().dual(), "octahedron");
69        assert!(duality.is_involutive());
70    }
71}