Coverage Report

Created: 2025-08-13 21:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/home/a220/proj/radnelac/src/day_cycle/prelude.rs
Line
Count
Source
1
// This Source Code Form is subject to the terms of the Mozilla Public
2
// License, v. 2.0. If a copy of the MPL was not distributed with this
3
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5
use crate::common::math::TermNum;
6
use crate::day_count::Fixed;
7
use num_traits::AsPrimitive;
8
use num_traits::FromPrimitive;
9
use num_traits::ToPrimitive;
10
use std::cmp::PartialEq;
11
use std::fmt::Debug;
12
13
pub trait BoundedCycle<const N: u8, const M: u8>:
14
    FromPrimitive + ToPrimitive + PartialEq + Debug
15
{
16
3.07k
    fn cycle_length() -> u8 {
17
3.07k
        N
18
3.07k
    }
19
20
40
    fn min() -> u8 {
21
40
        M
22
40
    }
23
24
40
    fn max() -> u8 {
25
40
        match M {
26
35
            0 => N - 1,
27
5
            1 => N,
28
0
            _ => panic!("M must be 0 or 1 for BoundedCycle"),
29
        }
30
40
    }
31
32
60.6k
    fn from_unbounded(x: i64) -> Self {
33
60.6k
        let m = match M {
34
28.4k
            0 => x.modulus(N.as_()),
35
32.2k
            1 => x.adjusted_remainder(N.as_()),
36
0
            _ => panic!("M must be 0 or 1 for BoundedCycle"),
37
        };
38
60.6k
        Self::from_i64(m).expect("Modulus guaranteed within range.")
39
60.6k
    }
40
41
21.0k
    fn to_unbounded(&self) -> i64 {
42
21.0k
        self.to_i64().expect("Guaranteed result")
43
21.0k
    }
44
}
45
46
pub trait OnOrBefore<const N: u8, const M: u8>: BoundedCycle<N, M> {
47
    fn raw_on_or_before(self, date: i64) -> Fixed;
48
49
13.3k
    fn on_or_before(self, date: Fixed) -> Fixed {
50
        //LISTING 1.62,1.69 (*Calendrical Calculations: The Ultimate Edition* by Reingold & Dershowitz.)
51
        //Modified to generalize across different day cycles
52
13.3k
        self.raw_on_or_before(date.get_day_i())
53
13.3k
    }
54
55
512
    fn on_or_after(self, date: Fixed) -> Fixed {
56
        //LISTING 1.65,1.69 (*Calendrical Calculations: The Ultimate Edition* by Reingold & Dershowitz.)
57
        //Modified to generalize across different day cycles
58
512
        self.raw_on_or_before(date.get_day_i() + ((Self::cycle_length() as i64) - 1))
59
512
    }
60
61
512
    fn nearest(self, date: Fixed) -> Fixed {
62
        //LISTING 1.66,1.69 (*Calendrical Calculations: The Ultimate Edition* by Reingold & Dershowitz.)
63
        //Modified to generalize across different day cycles
64
512
        self.raw_on_or_before(date.get_day_i() + ((Self::cycle_length() as i64) / 2))
65
512
    }
66
67
17.1k
    fn before(self, date: Fixed) -> Fixed {
68
        //LISTING 1.67,1.69 (*Calendrical Calculations: The Ultimate Edition* by Reingold & Dershowitz.)
69
        //Modified to generalize across different day cycles
70
17.1k
        self.raw_on_or_before(date.get_day_i() - 1)
71
17.1k
    }
72
73
513
    fn after(self, date: Fixed) -> Fixed {
74
        //LISTING 1.68,1.69 (*Calendrical Calculations: The Ultimate Edition* by Reingold & Dershowitz.)
75
        //Modified to generalize across different day cycles
76
513
        self.raw_on_or_before(date.get_day_i() + (Self::cycle_length() as i64))
77
513
    }
78
}