Skip to main content

use_johnson_solid/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4/// A Johnson solid identifier from `J1` through `J92`.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6pub struct JohnsonSolidId(u8);
7
8impl JohnsonSolidId {
9    /// Creates an identifier for `J1` through `J92`.
10    #[must_use]
11    pub const fn new(number: u8) -> Option<Self> {
12        if number >= 1 && number <= 92 {
13            Some(Self(number))
14        } else {
15            None
16        }
17    }
18
19    /// Returns the numeric part of the identifier.
20    #[must_use]
21    pub const fn number(self) -> u8 {
22        self.0
23    }
24
25    /// Returns the canonical `J` label.
26    #[must_use]
27    pub fn label(self) -> String {
28        format!("J{}", self.0)
29    }
30}
31
32/// A Johnson solid descriptor.
33#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34pub struct JohnsonSolid {
35    id: JohnsonSolidId,
36}
37
38impl JohnsonSolid {
39    /// Creates a Johnson solid descriptor.
40    #[must_use]
41    pub const fn new(id: JohnsonSolidId) -> Self {
42        Self { id }
43    }
44
45    /// Returns the Johnson solid identifier.
46    #[must_use]
47    pub const fn id(self) -> JohnsonSolidId {
48        self.id
49    }
50
51    /// Returns a selected common name when this crate carries one.
52    #[must_use]
53    pub const fn name(self) -> Option<&'static str> {
54        match self.id.number() {
55            1 => Some("square pyramid"),
56            2 => Some("pentagonal pyramid"),
57            3 => Some("triangular cupola"),
58            4 => Some("square cupola"),
59            5 => Some("pentagonal cupola"),
60            6 => Some("pentagonal rotunda"),
61            92 => Some("triangular hebesphenorotunda"),
62            _ => None,
63        }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::{JohnsonSolid, JohnsonSolidId};
70
71    #[test]
72    fn validates_johnson_solid_ids() {
73        let id = JohnsonSolidId::new(1).expect("valid id");
74        let solid = JohnsonSolid::new(id);
75
76        assert_eq!(id.number(), 1);
77        assert_eq!(id.label(), "J1");
78        assert_eq!(solid.name(), Some("square pyramid"));
79        assert_eq!(JohnsonSolidId::new(93), None);
80    }
81}