/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 | | } |