1use crate::{
17 objects::{Calendar, Dataset, ValidityPeriod},
18 Result,
19};
20use std::collections::BTreeSet;
21use typed_index_collection::CollectionWithId;
22
23fn get_validity_period(calendars: &CollectionWithId<Calendar>) -> Option<ValidityPeriod> {
24 let dates = calendars.values().fold(BTreeSet::new(), |acc, c| {
25 acc.union(&c.dates).cloned().collect()
26 });
27
28 if dates.is_empty() {
29 return None;
30 }
31
32 Some(ValidityPeriod {
33 start_date: *dates.iter().next().unwrap(),
34 end_date: *dates.iter().next_back().unwrap(),
35 })
36}
37
38pub fn compute_dataset_validity_period(
40 dataset: &mut Dataset,
41 calendars: &CollectionWithId<Calendar>,
42) -> Result<()> {
43 let validity_period = get_validity_period(calendars);
44
45 if let Some(vp) = validity_period {
46 dataset.start_date = vp.start_date;
47 dataset.end_date = vp.end_date;
48 }
49
50 Ok(())
51}
52
53pub fn set_dataset_validity_period(
58 dataset: &mut Dataset,
59 service_validity_period: &ValidityPeriod,
60) {
61 dataset.start_date = if service_validity_period.start_date < dataset.start_date {
62 service_validity_period.start_date
63 } else {
64 dataset.start_date
65 };
66 dataset.end_date = if service_validity_period.end_date > dataset.end_date {
67 service_validity_period.end_date
68 } else {
69 dataset.end_date
70 };
71}
72
73#[cfg(test)]
74mod tests {
75
76 mod set_validity_period {
77 use super::super::*;
78 use crate::objects::{Dataset, Date, ValidityPeriod};
79 use chrono::NaiveDate;
80 use pretty_assertions::assert_eq;
81
82 #[test]
83 fn no_existing_validity_period() {
84 let start_date = Date::from_ymd_opt(2019, 1, 1).unwrap();
85 let end_date = Date::from_ymd_opt(2019, 6, 30).unwrap();
86 let mut dataset = Dataset {
87 id: String::from("dataset_id"),
88 contributor_id: String::from("contributor_id"),
89 start_date: NaiveDate::MAX,
90 end_date: NaiveDate::MIN,
91 ..Default::default()
92 };
93 let service_validity_period = ValidityPeriod {
94 start_date,
95 end_date,
96 };
97 set_dataset_validity_period(&mut dataset, &service_validity_period);
98 assert_eq!(start_date, dataset.start_date);
99 assert_eq!(end_date, dataset.end_date);
100 }
101
102 #[test]
103 fn with_extended_validity_period() {
104 let start_date = Date::from_ymd_opt(2019, 1, 1).unwrap();
105 let end_date = Date::from_ymd_opt(2019, 6, 30).unwrap();
106 let mut dataset = Dataset {
107 id: String::from("dataset_id"),
108 contributor_id: String::from("contributor_id"),
109 start_date: Date::from_ymd_opt(2019, 3, 1).unwrap(),
110 end_date: Date::from_ymd_opt(2019, 4, 30).unwrap(),
111 ..Default::default()
112 };
113 let service_validity_period = ValidityPeriod {
114 start_date,
115 end_date,
116 };
117 set_dataset_validity_period(&mut dataset, &service_validity_period);
118 assert_eq!(start_date, dataset.start_date);
119 assert_eq!(end_date, dataset.end_date);
120 }
121
122 #[test]
123 fn with_included_validity_period() {
124 let start_date = Date::from_ymd_opt(2019, 1, 1).unwrap();
125 let end_date = Date::from_ymd_opt(2019, 6, 30).unwrap();
126 let mut dataset = Dataset {
127 id: String::from("dataset_id"),
128 contributor_id: String::from("contributor_id"),
129 start_date,
130 end_date,
131 ..Default::default()
132 };
133 let service_validity_period = ValidityPeriod {
134 start_date: Date::from_ymd_opt(2019, 3, 1).unwrap(),
135 end_date: Date::from_ymd_opt(2019, 4, 30).unwrap(),
136 };
137 set_dataset_validity_period(&mut dataset, &service_validity_period);
138 assert_eq!(start_date, dataset.start_date);
139 assert_eq!(end_date, dataset.end_date);
140 }
141 }
142
143 mod compute_dataset_validity_period {
144 use super::super::*;
145 use crate::{
146 calendars, configuration::*, file_handler::PathFileHandler, model::Collections,
147 test_utils::*,
148 };
149
150 #[test]
151 fn test_compute_dataset_validity_period() {
152 let calendars_content = "service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date\n\
153 1,1,1,1,1,1,0,0,20180501,20180508\n\
154 2,0,0,0,0,0,1,1,20180514,20180520";
155
156 let calendar_dates_content = "service_id,date,exception_type\n\
157 2,20180520,2";
158
159 test_in_tmp_dir(|path| {
160 let mut handler = PathFileHandler::new(path.to_path_buf());
161 create_file_with_content(path, "calendar.txt", calendars_content);
162 create_file_with_content(path, "calendar_dates.txt", calendar_dates_content);
163
164 let mut collections = Collections::default();
165 let (_, mut dataset, _) = read_config(None::<&str>).unwrap();
166
167 calendars::manage_calendars(&mut handler, &mut collections).unwrap();
168 compute_dataset_validity_period(&mut dataset, &collections.calendars).unwrap();
169
170 assert_eq!(
171 Dataset {
172 id: "default_dataset".to_string(),
173 contributor_id: "default_contributor".to_string(),
174 start_date: chrono::NaiveDate::from_ymd_opt(2018, 5, 1).unwrap(),
175 end_date: chrono::NaiveDate::from_ymd_opt(2018, 5, 19).unwrap(),
176 dataset_type: None,
177 extrapolation: false,
178 desc: None,
179 system: None,
180 },
181 dataset
182 );
183 });
184 }
185
186 #[test]
187 fn test_compute_dataset_validity_period_with_only_one_date() {
188 let calendars_content = "service_id,monday,tuesday,wednesday,thursday,friday,saturday,sunday,start_date,end_date\n\
189 1,1,1,1,1,1,0,0,20180501,20180501";
190
191 test_in_tmp_dir(|path| {
192 let mut handler = PathFileHandler::new(path.to_path_buf());
193 create_file_with_content(path, "calendar.txt", calendars_content);
194
195 let mut collections = Collections::default();
196 let (_, mut dataset, _) = read_config(None::<&str>).unwrap();
197
198 calendars::manage_calendars(&mut handler, &mut collections).unwrap();
199 compute_dataset_validity_period(&mut dataset, &collections.calendars).unwrap();
200
201 assert_eq!(
202 Dataset {
203 id: "default_dataset".to_string(),
204 contributor_id: "default_contributor".to_string(),
205 start_date: chrono::NaiveDate::from_ymd_opt(2018, 5, 1).unwrap(),
206 end_date: chrono::NaiveDate::from_ymd_opt(2018, 5, 1).unwrap(),
207 dataset_type: None,
208 extrapolation: false,
209 desc: None,
210 system: None,
211 },
212 dataset
213 );
214 });
215 }
216 }
217}