compact_calendar_cli/
config.rs1use crate::models::{DateDetail, DateRange};
2use chrono::NaiveDate;
3use serde::Deserialize;
4use std::collections::HashMap;
5
6#[derive(Debug, Deserialize)]
7pub struct CalendarConfig {
8 #[serde(default)]
9 pub dates: HashMap<String, RawDateDetail>,
10 #[serde(default)]
11 pub ranges: Vec<RawDateRange>,
12}
13
14#[derive(Debug, Deserialize, Clone)]
15pub struct RawDateDetail {
16 #[serde(default)]
17 pub description: String,
18 #[serde(default)]
19 pub color: Option<String>,
20}
21
22#[derive(Debug, Deserialize, Clone)]
23pub struct RawDateRange {
24 pub start: String,
25 pub end: String,
26 pub color: String,
27 #[serde(default)]
28 pub description: Option<String>,
29}
30
31impl CalendarConfig {
32 pub fn parse_dates(&self) -> HashMap<NaiveDate, DateDetail> {
33 self.dates
34 .iter()
35 .filter_map(|(date_str, detail)| {
36 NaiveDate::parse_from_str(date_str, "%Y-%m-%d")
37 .ok()
38 .map(|date| {
39 (
40 date,
41 DateDetail {
42 description: detail.description.clone(),
43 color: detail.color.clone(),
44 },
45 )
46 })
47 })
48 .collect()
49 }
50
51 pub fn parse_dates_for_year(&self, year: i32) -> HashMap<NaiveDate, DateDetail> {
52 self.dates
53 .iter()
54 .flat_map(|(date_str, detail)| {
55 if let Ok(date) = NaiveDate::parse_from_str(date_str, "%Y-%m-%d") {
56 return vec![(
57 date,
58 DateDetail {
59 description: detail.description.clone(),
60 color: detail.color.clone(),
61 },
62 )];
63 }
64 if let Ok(md) =
65 chrono::NaiveDate::parse_from_str(&format!("{}-{}", year, date_str), "%Y-%m-%d")
66 {
67 return vec![(
68 md,
69 DateDetail {
70 description: detail.description.clone(),
71 color: detail.color.clone(),
72 },
73 )];
74 }
75
76 vec![]
77 })
78 .collect()
79 }
80
81 pub fn parse_ranges(&self) -> Vec<DateRange> {
82 self.ranges
83 .iter()
84 .filter_map(|range| {
85 let start = NaiveDate::parse_from_str(&range.start, "%Y-%m-%d").ok()?;
86 let end = NaiveDate::parse_from_str(&range.end, "%Y-%m-%d").ok()?;
87 Some(DateRange {
88 start,
89 end,
90 color: range.color.clone(),
91 description: range.description.clone(),
92 })
93 })
94 .collect()
95 }
96
97 pub fn parse_ranges_for_year(&self, year: i32) -> Vec<DateRange> {
98 self.ranges
99 .iter()
100 .filter_map(|range| {
101 if let (Ok(start), Ok(end)) = (
102 NaiveDate::parse_from_str(&range.start, "%Y-%m-%d"),
103 NaiveDate::parse_from_str(&range.end, "%Y-%m-%d"),
104 ) {
105 return Some(DateRange {
106 start,
107 end,
108 color: range.color.clone(),
109 description: range.description.clone(),
110 });
111 }
112 if let (Ok(start), Ok(end)) = (
113 NaiveDate::parse_from_str(&format!("{}-{}", year, &range.start), "%Y-%m-%d"),
114 NaiveDate::parse_from_str(&format!("{}-{}", year, &range.end), "%Y-%m-%d"),
115 ) {
116 return Some(DateRange {
117 start,
118 end,
119 color: range.color.clone(),
120 description: range.description.clone(),
121 });
122 }
123
124 None
125 })
126 .collect()
127 }
128}