Complete backtracking, restriction violations, split model.rs into multiple files
This commit is contained in:
173
src-tauri/src/slot.rs
Normal file
173
src-tauri/src/slot.rs
Normal file
@@ -0,0 +1,173 @@
|
||||
use chrono::{Datelike, NaiveDate, Weekday};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, PartialOrd, Ord, Eq, Debug, Hash, Clone, Copy)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Slot {
|
||||
pub day: Day,
|
||||
pub position: ShiftPosition,
|
||||
}
|
||||
|
||||
impl Slot {
|
||||
pub fn new(day: Day, position: ShiftPosition) -> Self {
|
||||
Self { day, position }
|
||||
}
|
||||
|
||||
pub fn is_open_shift(&self) -> bool {
|
||||
self.day.is_open_shift()
|
||||
}
|
||||
|
||||
pub fn is_first(&self) -> bool {
|
||||
self.day == Day(1) && self.position == ShiftPosition::First
|
||||
}
|
||||
|
||||
pub fn is_open_second(&self) -> bool {
|
||||
self.is_open_shift() && self.position == ShiftPosition::Second
|
||||
}
|
||||
|
||||
pub fn next(&self) -> Self {
|
||||
match self.position {
|
||||
ShiftPosition::First if self.is_open_shift() => Self {
|
||||
day: self.day,
|
||||
position: ShiftPosition::Second,
|
||||
},
|
||||
_ => Self {
|
||||
day: self.day.next(),
|
||||
position: ShiftPosition::First,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn previous(&self) -> Self {
|
||||
match self.position {
|
||||
ShiftPosition::First => {
|
||||
let past_day = self.day.previous();
|
||||
if past_day.is_open_shift() {
|
||||
Self {
|
||||
day: past_day,
|
||||
position: ShiftPosition::Second,
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
day: past_day,
|
||||
position: ShiftPosition::First,
|
||||
}
|
||||
}
|
||||
}
|
||||
ShiftPosition::Second => Self {
|
||||
day: self.day,
|
||||
position: ShiftPosition::First,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn greater_than(&self, limit: u8) -> bool {
|
||||
self.day.greater_than(&Day(limit))
|
||||
}
|
||||
|
||||
pub fn default() -> Self {
|
||||
Self {
|
||||
day: Day(1),
|
||||
position: ShiftPosition::First,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, PartialOrd, Ord, Eq, Debug, Hash, Clone, Copy)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Day(pub u8);
|
||||
|
||||
impl Day {
|
||||
pub fn is_open_shift(&self) -> bool {
|
||||
!self.0.is_multiple_of(2)
|
||||
}
|
||||
|
||||
pub fn next(&self) -> Self {
|
||||
Self(self.0 + 1)
|
||||
}
|
||||
|
||||
pub fn previous(&self) -> Self {
|
||||
if self.0 <= 1 {
|
||||
Self(1)
|
||||
} else {
|
||||
Self(self.0 - 1)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn greater_than(&self, other: &Day) -> bool {
|
||||
self.0 > other.0
|
||||
}
|
||||
|
||||
pub fn is_weekend(&self, month: u32, year: i32) -> bool {
|
||||
let date = NaiveDate::from_ymd_opt(year, month, self.0 as u32).unwrap();
|
||||
let weekday = date.weekday();
|
||||
weekday == Weekday::Sat || weekday == Weekday::Sun
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, PartialOrd, Ord, Eq, Debug, Hash, Clone, Copy)]
|
||||
pub enum ShiftPosition {
|
||||
First,
|
||||
Second,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rstest::rstest;
|
||||
|
||||
use crate::slot::{Day, ShiftPosition, Slot};
|
||||
|
||||
#[rstest]
|
||||
fn test_slot() {
|
||||
let slot_1 = Slot::new(Day(1), ShiftPosition::First);
|
||||
let slot_2 = Slot::new(Day(1), ShiftPosition::Second);
|
||||
let slot_3 = Slot::new(Day(2), ShiftPosition::First);
|
||||
|
||||
assert!(slot_1.is_open_shift());
|
||||
assert!(slot_2.is_open_shift());
|
||||
assert!(!slot_3.is_open_shift());
|
||||
|
||||
assert!(slot_1.is_first());
|
||||
assert!(!slot_2.is_first());
|
||||
assert!(!slot_3.is_first());
|
||||
|
||||
assert!(!slot_1.is_open_second());
|
||||
assert!(slot_2.is_open_second());
|
||||
assert!(!slot_3.is_open_second());
|
||||
|
||||
assert_eq!(slot_1.next(), slot_2);
|
||||
assert_eq!(slot_2.next(), slot_3);
|
||||
|
||||
assert_eq!(slot_3.previous(), slot_2);
|
||||
assert_eq!(slot_2.previous(), slot_1);
|
||||
|
||||
assert!(!slot_1.greater_than(1));
|
||||
assert!(!slot_2.greater_than(1));
|
||||
assert!(slot_3.greater_than(1));
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_day() {
|
||||
let day_1 = Day(1);
|
||||
let day_2 = Day(2);
|
||||
let day_3 = Day(3);
|
||||
|
||||
assert!(day_1.is_open_shift());
|
||||
assert!(!day_2.is_open_shift());
|
||||
assert!(day_3.is_open_shift());
|
||||
|
||||
assert_eq!(day_1.next(), day_2);
|
||||
assert_eq!(day_2.next(), day_3);
|
||||
|
||||
assert_eq!(day_3.previous(), day_2);
|
||||
assert_eq!(day_2.previous(), day_1);
|
||||
|
||||
assert!(!day_1.greater_than(&day_1));
|
||||
assert!(day_2.greater_than(&day_1));
|
||||
assert!(day_3.greater_than(&day_1));
|
||||
|
||||
assert!(day_1.is_weekend(2, 2026));
|
||||
assert!(!day_2.is_weekend(2, 2026));
|
||||
assert!(!day_3.is_weekend(2, 2026));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user