Skip to main content

use_torus/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4use core::f64::consts::PI;
5
6/// A torus represented by major and minor radii.
7#[derive(Debug, Clone, Copy, PartialEq)]
8pub struct Torus {
9    major_radius: f64,
10    minor_radius: f64,
11}
12
13impl Torus {
14    /// Creates a torus with positive finite radii.
15    #[must_use]
16    pub const fn new(major_radius: f64, minor_radius: f64) -> Option<Self> {
17        if major_radius.is_finite()
18            && minor_radius.is_finite()
19            && major_radius > 0.0
20            && minor_radius > 0.0
21        {
22            Some(Self {
23                major_radius,
24                minor_radius,
25            })
26        } else {
27            None
28        }
29    }
30
31    /// Returns the major radius.
32    #[must_use]
33    pub const fn major_radius(self) -> f64 {
34        self.major_radius
35    }
36
37    /// Returns the minor radius.
38    #[must_use]
39    pub const fn minor_radius(self) -> f64 {
40        self.minor_radius
41    }
42
43    /// Returns the surface area.
44    #[must_use]
45    pub fn surface_area(self) -> f64 {
46        4.0 * PI * PI * self.major_radius * self.minor_radius
47    }
48
49    /// Returns the enclosed volume.
50    #[must_use]
51    pub fn volume(self) -> f64 {
52        2.0 * PI * PI * self.major_radius * self.minor_radius * self.minor_radius
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use core::f64::consts::PI;
59
60    use super::Torus;
61
62    fn approx_eq(left: f64, right: f64) -> bool {
63        (left - right).abs() < 1.0e-10
64    }
65
66    #[test]
67    fn computes_torus_measurements() {
68        let torus = Torus::new(3.0, 1.0).expect("valid torus");
69
70        assert_eq!(torus.major_radius(), 3.0);
71        assert_eq!(torus.minor_radius(), 1.0);
72        assert!(approx_eq(torus.surface_area(), 12.0 * PI * PI));
73        assert!(approx_eq(torus.volume(), 6.0 * PI * PI));
74        assert_eq!(Torus::new(3.0, 0.0), None);
75    }
76}