-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
✨ Calendar & initial impl for Matsudo #6
base: master
Are you sure you want to change the base?
Changes from all commits
b9e0469
d3cc114
fc3999f
ef332e7
ff496fa
f491665
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
use chrono::{DateTime, Local}; | ||
|
||
use crate::gomi::Gomi; | ||
|
||
pub(crate) mod matsudo; | ||
|
||
pub(crate) trait Calendar { | ||
fn gomi_at(&self, time: DateTime<Local>) -> Vec<Gomi>; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use crate::calendar::Calendar; | ||
use crate::gomi::Gomi; | ||
|
||
use chrono::{DateTime, Datelike, Local, Weekday, Weekday::*}; | ||
|
||
// Defines the gomi rules for Matsudo using a macro. | ||
macro_rules! matsudo_rules { | ||
( | ||
$current_base: expr, | ||
$current_time: expr, | ||
// This repetition represents each rules based on the base day. | ||
$(( | ||
$base: path, | ||
($burnable1: path, $burnable2: path, $burnable3: path), | ||
($glass_week_num: expr, $glass_week_day: path), // The Nth day of X | ||
$recycle_plastic: path, | ||
$other_plastic: path | ||
)),* | ||
$(,)? | ||
) => { | ||
// Matches the current base day for the location. | ||
match ($current_base) { | ||
$( | ||
$base => (vec![ | ||
match ($current_time.weekday()) { | ||
$base => Some(Gomi::new("資源ごみ")), | ||
$burnable1 | $burnable2 | $burnable3 => Some(Gomi::new("燃やせるごみ")), | ||
$recycle_plastic => Some(Gomi::new("リサイクルするプラスチック")), | ||
$other_plastic => Some(Gomi::new("その他のプラスチックなどのごみ")), | ||
_ => None, | ||
}, | ||
if (week_num_by_weekday($current_time, $glass_week_day) == $glass_week_num) { | ||
Some(Gomi::new("陶磁器・ガラスなどのごみ")) | ||
} else { | ||
None | ||
} | ||
] | ||
// Converts Vec<Option<Gomi>> to Vec<Gomi>, remaining only Some elements. | ||
.into_iter() | ||
.flat_map(|x| x) | ||
.collect() | ||
) | ||
),*, | ||
// Ignores the unknown base day, returning an empty Vec. | ||
_ => vec![], | ||
} | ||
} | ||
} | ||
|
||
pub(crate) struct Matsudo { | ||
base: Weekday, | ||
} | ||
|
||
impl Matsudo { | ||
pub(crate) fn new(base: Weekday) -> Self { | ||
Self { base } | ||
} | ||
} | ||
|
||
impl Calendar for Matsudo { | ||
fn gomi_at(&self, time: DateTime<Local>) -> Vec<Gomi> { | ||
// Using the defined rules, determines which Gomi's are available to take out. | ||
matsudo_rules!( | ||
self.base, | ||
time, | ||
(Mon, (Tue, Thu, Sat), (2, Thu), Wed, Fri), | ||
(Tue, (Mon, Wed, Fri), (2, Wed), Thu, Sat), | ||
(Wed, (Tue, Thu, Sat), (3, Thu), Fri, Mon), | ||
(Thu, (Mon, Wed, Fri), (3, Wed), Sat, Tue), | ||
(Fri, (Tue, Thu, Sat), (4, Thu), Mon, Wed), | ||
(Sat, (Mon, Wed, Fri), (4, Wed), Tue, Thu), | ||
) | ||
} | ||
} | ||
|
||
fn week_num_by_weekday(time: DateTime<Local>, weekday: Weekday) -> u32 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 今日が月の第何週目を求めるなら、一年における経過した週から今月までに経過した週を引いた方がスッキリするかも
|
||
time.day() / 7 | ||
+ if time.weekday().num_days_from_sunday() < weekday.num_days_from_sunday() { | ||
0 | ||
} else { | ||
1 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
use std::fmt::{Display, Formatter, Result}; | ||
|
||
pub(crate) struct Gomi { | ||
name: String, | ||
} | ||
|
||
impl Gomi { | ||
pub(crate) fn new(name: &str) -> Self { | ||
Self { | ||
name: name.to_string(), | ||
} | ||
} | ||
} | ||
|
||
impl Display for Gomi { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> Result { | ||
write!(f, "{}", self.name) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,21 @@ | ||
pub(crate) mod calendar; | ||
pub(crate) mod gomi; | ||
|
||
use chrono::{Local, TimeZone, Weekday}; | ||
|
||
use crate::calendar::Calendar; | ||
|
||
fn main() { | ||
println!("Hello, world!"); | ||
let calendar = calendar::matsudo::Matsudo::new(Weekday::Thu); | ||
let today = Local.ymd(2021, 3, 17).and_hms(0, 0, 0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 日付だけ見て処理するのであればDateTimeじゃなくてDateで処理した方がいいかも |
||
let gomi = calendar.gomi_at(today); | ||
|
||
println!( | ||
"今日 {} は {} の日です", | ||
today, | ||
gomi.iter() | ||
.map(|g| g.to_string()) | ||
.collect::<Vec<String>>() | ||
.join(", ") | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
第何週目しか見てなくて陶磁器・ガラスなどのごみの週に全て「陶磁器・ガラスなどのゴミ」が入っちゃってそう