Skip to main content

aura_anim_core/timing/
iteration.rs

1use std::num::NonZeroU32;
2
3/// Iteration configuration for a timing value.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct IterationCount {
6    kind: IterationCountKind,
7}
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub(crate) enum IterationCountKind {
11    Count(NonZeroU32),
12    Infinite,
13}
14
15impl IterationCount {
16    /// A single animation iteration.
17    pub const ONCE: Self = Self {
18        kind: IterationCountKind::Count(NonZeroU32::MIN),
19    };
20
21    /// An infinite number of iterations.
22    pub const INFINITE: Self = Self {
23        kind: IterationCountKind::Infinite,
24    };
25
26    /// Creates a finite iteration count, clamped to at least one iteration.
27    #[must_use]
28    pub fn count(count: u32) -> Self {
29        let count = NonZeroU32::new(count).unwrap_or(NonZeroU32::MIN);
30
31        Self {
32            kind: IterationCountKind::Count(count),
33        }
34    }
35
36    /// Returns an infinite iteration count.
37    #[must_use]
38    pub const fn infinite() -> Self {
39        Self::INFINITE
40    }
41
42    /// Returns the finite count when this value is not infinite.
43    #[must_use]
44    pub const fn finite_count(self) -> Option<u32> {
45        match self.kind {
46            IterationCountKind::Count(count) => Some(count.get()),
47            IterationCountKind::Infinite => None,
48        }
49    }
50}
51
52impl Default for IterationCount {
53    fn default() -> Self {
54        Self::ONCE
55    }
56}
57
58impl From<u32> for IterationCount {
59    fn from(value: u32) -> Self {
60        Self::count(value)
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::IterationCount;
67
68    #[test]
69    fn count_clamps_zero_to_one() {
70        assert_eq!(IterationCount::count(0).finite_count(), Some(1));
71        assert_eq!(IterationCount::count(3).finite_count(), Some(3));
72    }
73
74    #[test]
75    fn infinite_has_no_finite_count() {
76        assert_eq!(IterationCount::infinite().finite_count(), None);
77    }
78}