From 74f18a37a244ec92e04bfc4124b7778dc3268e4c Mon Sep 17 00:00:00 2001 From: Fredrik Meringdal Date: Sun, 25 Oct 2020 23:19:52 +0100 Subject: restructure files --- src/datetime.rs | 23 ++++++++ src/easter.rs | 43 -------------- src/iter/easter.rs | 43 ++++++++++++++ src/iter/iterinfo.rs | 6 +- src/iter/masks.rs | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/iter/mod.rs | 9 ++- src/iter/monthinfo.rs | 2 +- src/iter/poslist.rs | 2 +- src/iter/utils.rs | 8 +++ src/iter/yearinfo.rs | 37 +----------- src/lib.rs | 2 - src/masks.rs | 155 -------------------------------------------------- src/options.rs | 2 + src/parse_options.rs | 2 +- 14 files changed, 244 insertions(+), 245 deletions(-) delete mode 100644 src/easter.rs create mode 100644 src/iter/easter.rs create mode 100644 src/iter/masks.rs create mode 100644 src/iter/utils.rs delete mode 100644 src/masks.rs diff --git a/src/datetime.rs b/src/datetime.rs index 2e06d24..69cfb00 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -14,6 +14,29 @@ pub fn to_ordinal(date: &DateTime) -> isize { (date.timestamp() / 60 / 60 / 24) as isize } +pub fn is_leap_year(year: i32) -> bool { + year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) +} + +pub fn get_year_len(year: i32) -> usize { + if is_leap_year(year) { + return 366; + } + 365 +} + +pub fn get_weekday_val(wk: &Weekday) -> usize { + match wk { + Weekday::Mon => 0, + Weekday::Tue => 1, + Weekday::Wed => 2, + Weekday::Thu => 3, + Weekday::Fri => 4, + Weekday::Sat => 5, + Weekday::Sun => 6, + } +} + #[derive(Debug)] pub struct Time { pub hour: usize, diff --git a/src/easter.rs b/src/easter.rs deleted file mode 100644 index b41b270..0000000 --- a/src/easter.rs +++ /dev/null @@ -1,43 +0,0 @@ -use chrono::prelude::*; - -pub fn easter(y: isize, offset: isize) -> Vec { - let a = y % 19; - let b = (y as f32 / 100_f32).floor() as isize; - let c = y % 100; - let d = (b as f32 / 4_f32).floor() as isize; - let e = b % 4; - let f = ((b + 8) as f32 / 25_f32).floor() as isize; - let g = ((b - f + 1) as f32 / 3_f32).floor() as isize; - let h = (19 * a + b - d - g + 15) % 30; - let i = (c as f32 / 4_f32).floor() as isize; - let k = c % 4; - let l = (32 + 2 * e + 2 * i - h - k) % 7; - let m = ((a + 11 * h + 22 * l) as f32 / 451_f32).floor() as isize; - let month = ((h + l - 7 * m + 114) as f32 / 31_f32).floor() as u32; - let day = ((h + l - 7 * m + 114) % 31) + 1; - let date = Utc - .ymd(y as i32, month, (day + offset) as u32) - .and_hms(0, 0, 0); - let year_start = Utc.ymd(y as i32, 1, 1).and_hms(0, 0, 0); - return vec![ - ((date.timestamp() - year_start.timestamp()) as f32 / (60 * 60 * 24) as f32).ceil() - as isize, - ]; -} - -#[cfg(test)] -mod test_easter_masks { - use super::*; - - #[test] - fn easter_mask() { - let mask = easter(1997, 0); - assert_eq!(mask[0], 88); - let mask = easter(1998, 0); - assert_eq!(mask[0], 101); - let mask = easter(1999, 0); - assert_eq!(mask[0], 93); - let mask = easter(2000, 0); - assert_eq!(mask[0], 113); - } -} diff --git a/src/iter/easter.rs b/src/iter/easter.rs new file mode 100644 index 0000000..b41b270 --- /dev/null +++ b/src/iter/easter.rs @@ -0,0 +1,43 @@ +use chrono::prelude::*; + +pub fn easter(y: isize, offset: isize) -> Vec { + let a = y % 19; + let b = (y as f32 / 100_f32).floor() as isize; + let c = y % 100; + let d = (b as f32 / 4_f32).floor() as isize; + let e = b % 4; + let f = ((b + 8) as f32 / 25_f32).floor() as isize; + let g = ((b - f + 1) as f32 / 3_f32).floor() as isize; + let h = (19 * a + b - d - g + 15) % 30; + let i = (c as f32 / 4_f32).floor() as isize; + let k = c % 4; + let l = (32 + 2 * e + 2 * i - h - k) % 7; + let m = ((a + 11 * h + 22 * l) as f32 / 451_f32).floor() as isize; + let month = ((h + l - 7 * m + 114) as f32 / 31_f32).floor() as u32; + let day = ((h + l - 7 * m + 114) % 31) + 1; + let date = Utc + .ymd(y as i32, month, (day + offset) as u32) + .and_hms(0, 0, 0); + let year_start = Utc.ymd(y as i32, 1, 1).and_hms(0, 0, 0); + return vec![ + ((date.timestamp() - year_start.timestamp()) as f32 / (60 * 60 * 24) as f32).ceil() + as isize, + ]; +} + +#[cfg(test)] +mod test_easter_masks { + use super::*; + + #[test] + fn easter_mask() { + let mask = easter(1997, 0); + assert_eq!(mask[0], 88); + let mask = easter(1998, 0); + assert_eq!(mask[0], 101); + let mask = easter(1999, 0); + assert_eq!(mask[0], 93); + let mask = easter(2000, 0); + assert_eq!(mask[0], 113); + } +} diff --git a/src/iter/iterinfo.rs b/src/iter/iterinfo.rs index 09090f1..1d401dd 100644 --- a/src/iter/iterinfo.rs +++ b/src/iter/iterinfo.rs @@ -1,8 +1,8 @@ -use crate::datetime::*; -use crate::easter::*; +use crate::datetime::{Time, to_ordinal}; +use crate::iter::easter::easter; use crate::iter::monthinfo::{MonthInfo, rebuild_month}; use crate::iter::yearinfo::{YearInfo, rebuild_year}; -use crate::options::*; +use crate::options::{ParsedOptions, Frequenzy}; use chrono::prelude::*; pub struct IterInfo<'a> { diff --git a/src/iter/masks.rs b/src/iter/masks.rs new file mode 100644 index 0000000..8b2f6b0 --- /dev/null +++ b/src/iter/masks.rs @@ -0,0 +1,155 @@ +use once_cell::sync::Lazy; + +// ============================================================================= +// Date masks +// ============================================================================= + +// Every mask is 7 days longer to handle cross-year weekly periods. + +pub static MASKS: Lazy = Lazy::new(Masks::default); + +#[derive(Clone)] +pub struct Masks { + pub wday: Vec, + pub m365: Vec, + pub m365range: Vec, + pub m366: Vec, + pub m366range: Vec, + pub mday365: Vec, + pub mday366: Vec, + pub nmday365: Vec, + pub nmday366: Vec, +} + +impl Default for Masks { + fn default() -> Self { + let m28: Vec = (1..29).collect(); + let m29: Vec = (1..30).collect(); + let m30: Vec = (1..31).collect(); + let m31: Vec = (1..32).collect(); + + let nm28: Vec = (-28..0).collect(); + let nm29: Vec = (-29..0).collect(); + let nm30: Vec = (-30..0).collect(); + let nm31: Vec = (-31..0).collect(); + + Self { + wday: vec![(0..7).collect::>(); 55] + .into_iter() + .flatten() + .collect(), + m365: vec![ + vec![1; 31], + vec![2; 28], + vec![3; 31], + vec![4; 30], + vec![5; 31], + vec![6; 30], + vec![7; 31], + vec![8; 31], + vec![9; 30], + vec![10; 31], + vec![11; 30], + vec![12; 31], + vec![1; 7], + ] + .into_iter() + .flatten() + .collect(), + m365range: vec![0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365], + mday366: vec![ + m31.clone(), + m29, + m31.clone(), + m30.clone(), + m31.clone(), + m30.clone(), + m31.clone(), + m31.clone(), + m30.clone(), + m31.clone(), + m30.clone(), + m31.clone(), + Vec::from(&m31[0..7]), + ] + .into_iter() + .flatten() + .map(|d| d as isize) + .collect(), + m366range: vec![0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366], + mday365: vec![ + m31.clone(), + m28, + m31.clone(), + m30.clone(), + m31.clone(), + m30.clone(), + m31.clone(), + m31.clone(), + m30.clone(), + m31.clone(), + m30, + m31.clone(), + Vec::from(&m31[0..7]), + ] + .into_iter() + .flatten() + .map(|d| d as isize) + .collect(), + m366: vec![ + vec![1; 31], + vec![2; 29], + vec![3; 31], + vec![4; 30], + vec![5; 31], + vec![6; 30], + vec![7; 31], + vec![8; 31], + vec![9; 30], + vec![10; 31], + vec![11; 30], + vec![12; 31], + vec![1; 7], + ] + .into_iter() + .flatten() + .collect(), + nmday365: vec![ + nm31.clone(), + nm28, + nm31.clone(), + nm30.clone(), + nm31.clone(), + nm30.clone(), + nm31.clone(), + nm31.clone(), + nm30.clone(), + nm31.clone(), + nm30.clone(), + nm31.clone(), + Vec::from(&nm31[0..7]), + ] + .into_iter() + .flatten() + .collect(), + nmday366: vec![ + nm31.clone(), + nm29, + nm31.clone(), + nm30.clone(), + nm31.clone(), + nm30.clone(), + nm31.clone(), + nm31.clone(), + nm30.clone(), + nm31.clone(), + nm30, + nm31.clone(), + Vec::from(&nm31[0..7]), + ] + .into_iter() + .flatten() + .collect(), + } + } +} diff --git a/src/iter/mod.rs b/src/iter/mod.rs index d426a98..42cf58f 100644 --- a/src/iter/mod.rs +++ b/src/iter/mod.rs @@ -1,16 +1,15 @@ mod yearinfo; -use yearinfo::get_weekday_val; - mod monthinfo; - mod iterinfo; use iterinfo::IterInfo; - mod poslist; use poslist::build_poslist; +mod easter; +mod masks; +mod utils; use crate::options::*; -use crate::datetime::{Time, from_ordinal}; +use crate::datetime::{Time, from_ordinal, get_weekday_val}; use chrono::offset::TimeZone; use chrono::prelude::*; use chrono::{DateTime, Duration}; diff --git a/src/iter/monthinfo.rs b/src/iter/monthinfo.rs index c89bfc3..9da2ca6 100644 --- a/src/iter/monthinfo.rs +++ b/src/iter/monthinfo.rs @@ -1,5 +1,5 @@ use crate::options::*; -use crate::iter::yearinfo::pymod; +use crate::iter::utils::pymod; #[derive(Debug)] pub struct MonthInfo { diff --git a/src/iter/poslist.rs b/src/iter/poslist.rs index fa9fbd8..421d352 100644 --- a/src/iter/poslist.rs +++ b/src/iter/poslist.rs @@ -1,6 +1,6 @@ use crate::datetime::*; use crate::iter::iterinfo::IterInfo; -use crate::iter::yearinfo::pymod; +use crate::iter::utils::pymod; use crate::datetime::from_ordinal; use chrono::prelude::*; use chrono_tz::Tz; diff --git a/src/iter/utils.rs b/src/iter/utils.rs new file mode 100644 index 0000000..c168c92 --- /dev/null +++ b/src/iter/utils.rs @@ -0,0 +1,8 @@ +pub fn pymod(a: isize, b: isize) -> isize { + let r = a % b; + // If r and b differ in sign, add b to wrap the result to the correct sign. + if (r > 0 && b < 0) || (r < 0 && b > 0) { + return r + b; + } + r +} \ No newline at end of file diff --git a/src/iter/yearinfo.rs b/src/iter/yearinfo.rs index 8a944f7..40b48ce 100644 --- a/src/iter/yearinfo.rs +++ b/src/iter/yearinfo.rs @@ -1,7 +1,8 @@ -use crate::masks::MASKS; +use crate::iter::masks::MASKS; use crate::options::*; use chrono::prelude::*; -use crate::datetime::to_ordinal; +use crate::datetime::{to_ordinal, get_year_len, get_weekday_val}; +use crate::iter::utils::pymod; #[derive(Debug)] @@ -18,29 +19,6 @@ pub struct YearInfo { pub wnomask: Option>, } -fn is_leap_year(year: i32) -> bool { - year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) -} - -fn get_year_len(year: i32) -> usize { - if is_leap_year(year) { - return 366; - } - 365 -} - -pub fn get_weekday_val(wk: &Weekday) -> usize { - match wk { - Weekday::Mon => 0, - Weekday::Tue => 1, - Weekday::Wed => 2, - Weekday::Thu => 3, - Weekday::Fri => 4, - Weekday::Sat => 5, - Weekday::Sun => 6, - } -} - pub struct BaseMasks { mmask: Vec, mdaymask: Vec, @@ -74,15 +52,6 @@ fn base_year_masks(year: i32) -> BaseMasks { } } -pub fn pymod(a: isize, b: isize) -> isize { - let r = a % b; - // If r and b differ in sign, add b to wrap the result to the correct sign. - if (r > 0 && b < 0) || (r < 0 && b > 0) { - return r + b; - } - r -} - pub fn rebuild_year(year: i32, options: &ParsedOptions) -> YearInfo { let firstyday = Utc.ymd(year, 1, 1).and_hms_milli(0, 0, 0, 0); diff --git a/src/lib.rs b/src/lib.rs index 17d9ce1..6740b10 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,9 +38,7 @@ extern crate once_cell; extern crate regex; mod datetime; -mod easter; mod iter; -mod masks; mod parse_options; mod options; mod rrulestr; diff --git a/src/masks.rs b/src/masks.rs deleted file mode 100644 index 8b2f6b0..0000000 --- a/src/masks.rs +++ /dev/null @@ -1,155 +0,0 @@ -use once_cell::sync::Lazy; - -// ============================================================================= -// Date masks -// ============================================================================= - -// Every mask is 7 days longer to handle cross-year weekly periods. - -pub static MASKS: Lazy = Lazy::new(Masks::default); - -#[derive(Clone)] -pub struct Masks { - pub wday: Vec, - pub m365: Vec, - pub m365range: Vec, - pub m366: Vec, - pub m366range: Vec, - pub mday365: Vec, - pub mday366: Vec, - pub nmday365: Vec, - pub nmday366: Vec, -} - -impl Default for Masks { - fn default() -> Self { - let m28: Vec = (1..29).collect(); - let m29: Vec = (1..30).collect(); - let m30: Vec = (1..31).collect(); - let m31: Vec = (1..32).collect(); - - let nm28: Vec = (-28..0).collect(); - let nm29: Vec = (-29..0).collect(); - let nm30: Vec = (-30..0).collect(); - let nm31: Vec = (-31..0).collect(); - - Self { - wday: vec![(0..7).collect::>(); 55] - .into_iter() - .flatten() - .collect(), - m365: vec![ - vec![1; 31], - vec![2; 28], - vec![3; 31], - vec![4; 30], - vec![5; 31], - vec![6; 30], - vec![7; 31], - vec![8; 31], - vec![9; 30], - vec![10; 31], - vec![11; 30], - vec![12; 31], - vec![1; 7], - ] - .into_iter() - .flatten() - .collect(), - m365range: vec![0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365], - mday366: vec![ - m31.clone(), - m29, - m31.clone(), - m30.clone(), - m31.clone(), - m30.clone(), - m31.clone(), - m31.clone(), - m30.clone(), - m31.clone(), - m30.clone(), - m31.clone(), - Vec::from(&m31[0..7]), - ] - .into_iter() - .flatten() - .map(|d| d as isize) - .collect(), - m366range: vec![0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366], - mday365: vec![ - m31.clone(), - m28, - m31.clone(), - m30.clone(), - m31.clone(), - m30.clone(), - m31.clone(), - m31.clone(), - m30.clone(), - m31.clone(), - m30, - m31.clone(), - Vec::from(&m31[0..7]), - ] - .into_iter() - .flatten() - .map(|d| d as isize) - .collect(), - m366: vec![ - vec![1; 31], - vec![2; 29], - vec![3; 31], - vec![4; 30], - vec![5; 31], - vec![6; 30], - vec![7; 31], - vec![8; 31], - vec![9; 30], - vec![10; 31], - vec![11; 30], - vec![12; 31], - vec![1; 7], - ] - .into_iter() - .flatten() - .collect(), - nmday365: vec![ - nm31.clone(), - nm28, - nm31.clone(), - nm30.clone(), - nm31.clone(), - nm30.clone(), - nm31.clone(), - nm31.clone(), - nm30.clone(), - nm31.clone(), - nm30.clone(), - nm31.clone(), - Vec::from(&nm31[0..7]), - ] - .into_iter() - .flatten() - .collect(), - nmday366: vec![ - nm31.clone(), - nm29, - nm31.clone(), - nm30.clone(), - nm31.clone(), - nm30.clone(), - nm31.clone(), - nm31.clone(), - nm30.clone(), - nm31.clone(), - nm30, - nm31.clone(), - Vec::from(&nm31[0..7]), - ] - .into_iter() - .flatten() - .collect(), - } - } -} diff --git a/src/options.rs b/src/options.rs index 2bface8..5599454 100644 --- a/src/options.rs +++ b/src/options.rs @@ -35,6 +35,7 @@ pub struct ParsedOptions { pub byeaster: Option, } +// TODO: PartialOptions shouldnt have all of these fields #[derive(Debug, Clone)] pub struct PartialOptions { pub freq: Option, @@ -83,6 +84,7 @@ impl PartialOptions { } } + // TODO: better name fn is_some_or_none<'a, T>(prop1: &'a Option, prop2: &'a Option) -> &'a Option { if prop2.is_some() { return prop2; diff --git a/src/parse_options.rs b/src/parse_options.rs index 2df90be..b7926ef 100644 --- a/src/parse_options.rs +++ b/src/parse_options.rs @@ -2,7 +2,7 @@ use chrono::prelude::*; use crate::options::{ParsedOptions, Frequenzy, PartialOptions}; use chrono_tz::{Tz, UTC}; -// TODO: make this method on partialoptions struct +// TODO: Validation pub fn parse_options(options: &PartialOptions) -> ParsedOptions { let mut default_partial_options = PartialOptions::new(); default_partial_options.interval = Some(1); -- cgit v1.2.3