gistools/readers/gtfs/schedule/calendar_dates.rs
1use crate::{
2 readers::{csv::parse_csv_as_record, parse_gtfs_date},
3 util::Date,
4};
5use alloc::{collections::BTreeMap, string::String};
6use s2json::MValueCompatible;
7
8/// Describes whether service is added or removed on a specific date.
9/// 1 - Service added for this date.
10/// 2 - Service removed for this date.
11#[derive(Debug, Clone, Copy, PartialEq)]
12pub enum GTFSExceptionType {
13 /// Service added for this date.
14 Added = 1,
15 /// Service removed for this date.
16 Removed = 2,
17}
18impl From<i8> for GTFSExceptionType {
19 fn from(s: i8) -> Self {
20 match s {
21 2 => GTFSExceptionType::Removed,
22 _ => GTFSExceptionType::Added,
23 }
24 }
25}
26
27/// # Calendar Dates
28///
29/// **Conditionally Required**
30/// Explicitly activates or disables service on particular dates.
31/// - If used with `calendar.txt`, it modifies the default service patterns.
32/// - If `calendar.txt` is omitted, all service dates must be listed here.
33#[derive(Debug, Default, Clone, PartialEq, MValueCompatible)]
34pub struct GTFSCalendarDate {
35 /// **Required**
36 /// Identifies a set of dates where service exception occurs.
37 /// References `calendar.service_id` if used with `calendar.txt`;
38 /// or acts as a standalone ID if `calendar.txt` is omitted.
39 pub service_id: String,
40 /// **Required**
41 /// Date of the service exception, parsed as a JavaScript Date.
42 /// Originally in GTFS as a YYYYMMDD string (no time component).
43 pub date: String,
44 /// **Required**
45 /// Indicates whether service is added (1) or removed (2) on this date.
46 pub exception_type: i8,
47}
48impl GTFSCalendarDate {
49 /// Create a new GTFSCalendarDate
50 pub fn new(source: &str) -> BTreeMap<String, GTFSCalendarDate> {
51 let mut res = BTreeMap::new();
52 for record in parse_csv_as_record::<GTFSCalendarDate>(source, None, None) {
53 res.insert(record.service_id.clone(), record);
54 }
55 res
56 }
57 /// Get the exception type
58 pub fn exception_type(&self) -> GTFSExceptionType {
59 self.exception_type.into()
60 }
61 /// Get the date
62 pub fn date(&self) -> Date {
63 parse_gtfs_date(&self.date).unwrap_or_default()
64 }
65}