1use crate::model::Collections;
18use derivative::Derivative;
19use std::collections::HashMap;
20use typed_index_collection::{Collection, CollectionWithId, Id};
21
22#[derive(Derivative, Debug)]
24#[derivative(Default)]
25pub struct PrefixConfiguration {
26 #[derivative(Default(value = "\":\".to_string()"))]
28 sep: String,
29 data_prefix: Option<String>,
33 schedule_subprefix: Option<String>,
37}
38
39impl PrefixConfiguration {
40 pub fn set_sep<S>(&mut self, sep: S)
42 where
43 S: ToString,
44 {
45 self.sep = sep.to_string();
46 }
47
48 pub fn set_data_prefix<S>(&mut self, data_prefix: S)
50 where
51 S: ToString,
52 {
53 self.data_prefix = Some(data_prefix.to_string());
54 }
55
56 pub fn set_schedule_subprefix<S>(&mut self, schedule_subprefix: S)
58 where
59 S: ToString,
60 {
61 self.schedule_subprefix = Some(schedule_subprefix.to_string());
62 }
63
64 pub fn referential_prefix(&self, id: &str) -> String {
68 let mut prefix = String::new();
69 if let Some(data_prefix) = self.data_prefix.as_ref() {
70 prefix = prefix + data_prefix + &self.sep;
71 }
72 prefix + id
73 }
74
75 pub fn schedule_prefix(&self, id: &str) -> String {
79 let mut prefix = String::new();
80 if let Some(data_prefix) = self.data_prefix.as_ref() {
81 prefix = prefix + data_prefix + &self.sep;
82 }
83 if let Some(schedule_subprefix) = self.schedule_subprefix.as_ref() {
84 prefix = prefix + schedule_subprefix + &self.sep;
85 }
86 prefix + id
87 }
88}
89
90pub trait AddPrefix {
92 #[deprecated(since = "0.24.0", note = "please use `AddPrefix::prefix()` instead")]
94 fn add_prefix(&mut self, prefix: &str) {
95 let prefix_conf = PrefixConfiguration {
96 sep: String::new(),
97 data_prefix: Some(prefix.to_string()),
98 schedule_subprefix: None,
99 };
100 self.prefix(&prefix_conf);
101 }
102
103 #[deprecated(since = "0.24.0", note = "please use `AddPrefix::prefix()` instead")]
106 fn add_prefix_with_sep(&mut self, prefix: &str, sep: &str) {
107 let prefix_conf = PrefixConfiguration {
108 sep: String::from(sep),
109 data_prefix: Some(prefix.to_string()),
110 schedule_subprefix: None,
111 };
112 self.prefix(&prefix_conf);
113 }
114
115 fn prefix(&mut self, prefix_conf: &PrefixConfiguration);
119}
120
121impl<T> AddPrefix for Collection<T>
122where
123 T: AddPrefix,
124{
125 fn prefix(&mut self, prefix_conf: &PrefixConfiguration) {
126 for obj in &mut self.values_mut() {
127 obj.prefix(prefix_conf);
128 }
129 }
130}
131
132impl<T> AddPrefix for CollectionWithId<T>
133where
134 T: Id<T> + AddPrefix,
135{
136 fn prefix(&mut self, prefix_conf: &PrefixConfiguration) {
137 for index in self.indexes() {
138 self.index_mut(index).prefix(prefix_conf);
139 }
140 }
141}
142
143fn add_prefix_on_vehicle_journey_ids(
144 vehicle_journey_ids: &HashMap<(String, u32), String>,
145 prefix_conf: &PrefixConfiguration,
146) -> HashMap<(String, u32), String> {
147 vehicle_journey_ids
148 .iter()
149 .map(|((trip_id, sequence), value)| {
150 (
151 (prefix_conf.schedule_prefix(trip_id.as_str()), *sequence),
152 value.to_string(),
153 )
154 })
155 .collect()
156}
157
158fn add_prefix_on_vehicle_journey_ids_and_values(
159 vehicle_journey_ids: &HashMap<(String, u32), String>,
160 prefix_conf: &PrefixConfiguration,
161) -> HashMap<(String, u32), String> {
162 vehicle_journey_ids
163 .iter()
164 .map(|((trip_id, sequence), value)| {
165 (
166 (prefix_conf.schedule_prefix(trip_id.as_str()), *sequence),
167 prefix_conf.schedule_prefix(value.as_str()),
168 )
169 })
170 .collect()
171}
172
173impl AddPrefix for Collections {
174 fn prefix(&mut self, prefix_conf: &PrefixConfiguration) {
175 self.contributors.prefix(prefix_conf);
176 self.datasets.prefix(prefix_conf);
177 self.networks.prefix(prefix_conf);
178 self.lines.prefix(prefix_conf);
179 self.routes.prefix(prefix_conf);
180 self.vehicle_journeys.prefix(prefix_conf);
181 self.frequencies.prefix(prefix_conf);
182 self.stop_areas.prefix(prefix_conf);
183 self.stop_points.prefix(prefix_conf);
184 self.stop_locations.prefix(prefix_conf);
185 self.calendars.prefix(prefix_conf);
186 self.companies.prefix(prefix_conf);
187 self.comments.prefix(prefix_conf);
188 self.equipments.prefix(prefix_conf);
189 self.transfers.prefix(prefix_conf);
190 self.trip_properties.prefix(prefix_conf);
191 self.geometries.prefix(prefix_conf);
192 self.admin_stations.prefix(prefix_conf);
193 self.prices_v1.prefix(prefix_conf);
194 self.od_fares_v1.prefix(prefix_conf);
195 self.fares_v1.prefix(prefix_conf);
196 self.tickets.prefix(prefix_conf);
197 self.ticket_prices.prefix(prefix_conf);
198 self.ticket_uses.prefix(prefix_conf);
199 self.ticket_use_perimeters.prefix(prefix_conf);
200 self.ticket_use_restrictions.prefix(prefix_conf);
201 self.pathways.prefix(prefix_conf);
202 self.levels.prefix(prefix_conf);
203 self.grid_calendars.prefix(prefix_conf);
204 self.grid_exception_dates.prefix(prefix_conf);
205 self.grid_periods.prefix(prefix_conf);
206 self.grid_rel_calendar_line.prefix(prefix_conf);
207 self.occupancies.prefix(prefix_conf);
208 self.stop_time_headsigns =
209 add_prefix_on_vehicle_journey_ids(&self.stop_time_headsigns, prefix_conf);
210 self.stop_time_ids =
211 add_prefix_on_vehicle_journey_ids_and_values(&self.stop_time_ids, prefix_conf);
212 self.stop_time_comments =
213 add_prefix_on_vehicle_journey_ids_and_values(&self.stop_time_comments, prefix_conf);
214 }
215}
216
217#[cfg(test)]
218mod tests {
219 use super::*;
220 use pretty_assertions::assert_eq;
221
222 struct Obj(String);
223 impl Id<Obj> for Obj {
224 fn id(&self) -> &str {
225 self.0.as_str()
226 }
227 fn set_id(&mut self, _id: String) {
228 unimplemented!()
229 }
230 }
231 impl AddPrefix for Obj {
232 fn prefix(&mut self, prefix_conf: &PrefixConfiguration) {
233 self.0 = prefix_conf.schedule_prefix(self.0.as_str());
234 }
235 }
236
237 #[test]
238 fn collection_referential() {
239 let obj1 = Obj(String::from("some_id"));
240 let obj2 = Obj(String::from("other_id"));
241 let mut collection = Collection::new(vec![obj1, obj2]);
242 let mut prefix_conf = PrefixConfiguration::default();
243 prefix_conf.set_data_prefix("pre");
244 collection.prefix(&prefix_conf);
245 let mut values = collection.values();
246 let element = values.next().unwrap();
247 assert_eq!(String::from("pre:some_id"), element.0);
248 let element = values.next().unwrap();
249 assert_eq!(String::from("pre:other_id"), element.0);
250 }
251
252 #[test]
253 fn collection_referential_and_schedule() {
254 let obj1 = Obj(String::from("some_id"));
255 let obj2 = Obj(String::from("other_id"));
256 let mut collection = Collection::new(vec![obj1, obj2]);
257 let mut prefix_conf = PrefixConfiguration::default();
258 prefix_conf.set_data_prefix("pre");
259 prefix_conf.set_schedule_subprefix("winter");
260 collection.prefix(&prefix_conf);
261 let mut values = collection.values();
262 let element = values.next().unwrap();
263 assert_eq!(String::from("pre:winter:some_id"), element.0);
264 let element = values.next().unwrap();
265 assert_eq!(String::from("pre:winter:other_id"), element.0);
266 }
267
268 #[test]
269 fn collection_schedule() {
270 let obj1 = Obj(String::from("some_id"));
271 let obj2 = Obj(String::from("other_id"));
272 let mut collection = Collection::new(vec![obj1, obj2]);
273 let mut prefix_conf = PrefixConfiguration::default();
274 prefix_conf.set_schedule_subprefix("winter");
275 collection.prefix(&prefix_conf);
276 let mut values = collection.values();
277 let element = values.next().unwrap();
278 assert_eq!(String::from("winter:some_id"), element.0);
279 let element = values.next().unwrap();
280 assert_eq!(String::from("winter:other_id"), element.0);
281 }
282
283 #[test]
284 fn collection_no_prefix() {
285 let obj1 = Obj(String::from("some_id"));
286 let obj2 = Obj(String::from("other_id"));
287 let mut collection = Collection::new(vec![obj1, obj2]);
288 let prefix_conf = PrefixConfiguration::default();
289 collection.prefix(&prefix_conf);
290 let mut values = collection.values();
291 let element = values.next().unwrap();
292 assert_eq!(String::from("some_id"), element.0);
293 let element = values.next().unwrap();
294 assert_eq!(String::from("other_id"), element.0);
295 }
296
297 #[test]
298 #[allow(deprecated)]
299 fn collection_deprecated() {
300 let obj1 = Obj(String::from("some_id"));
301 let obj2 = Obj(String::from("other_id"));
302 let mut collection = Collection::new(vec![obj1, obj2]);
303 collection.add_prefix("pre:");
304 let mut values = collection.values();
305 let element = values.next().unwrap();
306 assert_eq!(String::from("pre:some_id"), element.0);
307 let element = values.next().unwrap();
308 assert_eq!(String::from("pre:other_id"), element.0);
309 }
310
311 #[test]
312 fn collection_with_id_referential() {
313 let obj1 = Obj(String::from("some_id"));
314 let obj2 = Obj(String::from("other_id"));
315 let mut collection = CollectionWithId::new(vec![obj1, obj2]).unwrap();
316 let mut prefix_conf = PrefixConfiguration::default();
317 prefix_conf.set_data_prefix("pre");
318 collection.prefix(&prefix_conf);
319 let mut values = collection.values();
320 let element = values.next().unwrap();
321 assert_eq!(String::from("pre:some_id"), element.0);
322 let element = values.next().unwrap();
323 assert_eq!(String::from("pre:other_id"), element.0);
324 }
325
326 #[test]
327 fn collection_with_id_referential_and_schedule() {
328 let obj1 = Obj(String::from("some_id"));
329 let obj2 = Obj(String::from("other_id"));
330 let mut collection = CollectionWithId::new(vec![obj1, obj2]).unwrap();
331 let mut prefix_conf = PrefixConfiguration::default();
332 prefix_conf.set_data_prefix("pre");
333 prefix_conf.set_schedule_subprefix("summer");
334 collection.prefix(&prefix_conf);
335 let mut values = collection.values();
336 let element = values.next().unwrap();
337 assert_eq!(String::from("pre:summer:some_id"), element.0);
338 let element = values.next().unwrap();
339 assert_eq!(String::from("pre:summer:other_id"), element.0);
340 }
341
342 #[test]
343 fn collection_with_id_schedule() {
344 let obj1 = Obj(String::from("some_id"));
345 let obj2 = Obj(String::from("other_id"));
346 let mut collection = CollectionWithId::new(vec![obj1, obj2]).unwrap();
347 let mut prefix_conf = PrefixConfiguration::default();
348 prefix_conf.set_schedule_subprefix("summer");
349 collection.prefix(&prefix_conf);
350 let mut values = collection.values();
351 let element = values.next().unwrap();
352 assert_eq!(String::from("summer:some_id"), element.0);
353 let element = values.next().unwrap();
354 assert_eq!(String::from("summer:other_id"), element.0);
355 }
356
357 #[test]
358 fn collection_with_id_no_prefix() {
359 let obj1 = Obj(String::from("some_id"));
360 let obj2 = Obj(String::from("other_id"));
361 let mut collection = CollectionWithId::new(vec![obj1, obj2]).unwrap();
362 let prefix_conf = PrefixConfiguration::default();
363 collection.prefix(&prefix_conf);
364 let mut values = collection.values();
365 let element = values.next().unwrap();
366 assert_eq!(String::from("some_id"), element.0);
367 let element = values.next().unwrap();
368 assert_eq!(String::from("other_id"), element.0);
369 }
370
371 #[test]
372 #[allow(deprecated)]
373 fn collection_with_id_deprecated() {
374 let obj1 = Obj(String::from("some_id"));
375 let obj2 = Obj(String::from("other_id"));
376 let mut collection = CollectionWithId::new(vec![obj1, obj2]).unwrap();
377 collection.add_prefix("pre:");
378 let mut values = collection.values();
379 let element = values.next().unwrap();
380 assert_eq!(String::from("pre:some_id"), element.0);
381 let element = values.next().unwrap();
382 assert_eq!(String::from("pre:other_id"), element.0);
383 }
384}