diff options
Diffstat (limited to 'rust/schist_models/src')
| -rw-r--r-- | rust/schist_models/src/budget_drip.rs | 2 | ||||
| -rw-r--r-- | rust/schist_models/src/date_utc.rs | 65 |
2 files changed, 66 insertions, 1 deletions
diff --git a/rust/schist_models/src/budget_drip.rs b/rust/schist_models/src/budget_drip.rs index f467ecd..2cc2c63 100644 --- a/rust/schist_models/src/budget_drip.rs +++ b/rust/schist_models/src/budget_drip.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use crate::date_utc::DateUtc; -#[derive(Builder, Queryable, Identifiable, Selectable, Debug, PartialEq, Serialize, Deserialize, Insertable)] +#[derive(Builder, Clone, Copy, Queryable, Identifiable, Selectable, Debug, PartialEq, Serialize, Deserialize, Insertable)] #[diesel(table_name = crate::schema::budget_drips)] pub struct BudgetDrip { pub id: i32, diff --git a/rust/schist_models/src/date_utc.rs b/rust/schist_models/src/date_utc.rs index 3f5391c..c801585 100644 --- a/rust/schist_models/src/date_utc.rs +++ b/rust/schist_models/src/date_utc.rs @@ -24,6 +24,7 @@ use crate::datetime_utc::DatetimeUtc; Serialize, Deserialize, Clone, + Copy, Debug, AsExpression, FromSqlRow, @@ -55,6 +56,19 @@ impl DateUtc { .abs_diff(other.chrono_datetime_utc.num_days_from_ce()) } + pub fn days_in_month(&self) -> u32 { + self.first_day_in_next_month().day_diff(&self.first_day_in_month()) + } + + pub fn add_days(&self, days: u64) -> Result<Self> { + let chrono_datetime_utc = self + .chrono_datetime_utc + .checked_add_days(chrono::Days::new(days)) + .with_context(|| format!("failed to add {} days to {}", days, self)) + .unwrap(); + Ok(Self { chrono_datetime_utc }) + } + fn is_day_str(str: &str) -> bool { if str.len() != 10 { return false; @@ -72,6 +86,42 @@ impl DateUtc { } return true; } + + fn first_day_in_next_month(&self) -> Self { + let month = self.month(); + let mut curr_guess: Option<DateTime<Utc>> = None; + let mut curr_add = 1; + while curr_guess.is_none() || curr_guess.unwrap().month() == month { + curr_guess = self.chrono_datetime_utc.checked_add_days(chrono::Days::new(curr_add)); + curr_add = curr_add + 1; + }; + return Self { chrono_datetime_utc: curr_guess.unwrap() }; + } + + fn first_day_in_month(&self) -> Self { + let month = self.month(); + let mut prev_guess = self.clone(); + let mut curr_guess = self.clone(); + let mut curr_subtractor = 1; + while curr_guess.month() == month { + prev_guess = curr_guess.clone(); + + let mut next: Option<DateTime<Utc>> = None; + while next.is_none() { + if curr_subtractor > 31 { + return prev_guess; + } + next = self.chrono_datetime_utc.checked_sub_days(chrono::Days::new(curr_subtractor)); + curr_subtractor = curr_subtractor + 1; + } + let next = next.unwrap(); + + curr_guess = Self { + chrono_datetime_utc: next, + }; + }; + return prev_guess; + } } impl Nowlike for DateUtc { @@ -306,4 +356,19 @@ mod test { assert_eq!(day_diff, 1); assert_eq!(day_diff, neg_day_diff); } + + #[test] + fn test_first_day_in_month() { + todo!(); + } + + #[test] + fn test_first_day_in_next_month() { + todo!(); + } + + #[test] + fn test_days_in_month() { + todo!(); + } } |
