1use crate::schedule::Schedule;
4use crate::stop::StopId;
5
6pub type RouteId = u64;
8
9#[derive(Debug, Clone)]
11pub struct Route {
12 pub id: RouteId,
14 pub name: String,
16 pub stops: Vec<StopId>,
18 pub inter_stop_times: Vec<f64>,
20 pub schedule: Schedule,
22}
23
24impl Route {
25 pub fn new(
27 id: RouteId,
28 name: impl Into<String>,
29 stops: Vec<StopId>,
30 inter_stop_times: Vec<f64>,
31 schedule: Schedule,
32 ) -> Self {
33 assert!(stops.len() >= 2, "route needs at least two stops");
34 assert_eq!(
35 inter_stop_times.len(),
36 stops.len() - 1,
37 "inter_stop_times length must be stops.len() - 1"
38 );
39 Self {
40 id,
41 name: name.into(),
42 stops,
43 inter_stop_times,
44 schedule,
45 }
46 }
47
48 pub fn scheduled_runtime(&self) -> f64 {
50 self.inter_stop_times.iter().sum()
51 }
52
53 pub fn index_of(&self, stop_id: StopId) -> Option<usize> {
56 self.stops.iter().position(|s| *s == stop_id)
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn route_runtime_sums_inter_stop() {
66 let r = Route::new(
67 42,
68 "N17",
69 vec![1, 2, 3, 4],
70 vec![60.0, 90.0, 75.0],
71 Schedule::fixed_headway(600.0),
72 );
73 assert_eq!(r.scheduled_runtime(), 225.0);
74 assert_eq!(r.index_of(3), Some(2));
75 }
76
77 #[test]
78 #[should_panic]
79 fn inter_stop_length_mismatch_panics() {
80 Route::new(
81 1,
82 "bad",
83 vec![1, 2, 3],
84 vec![60.0], Schedule::fixed_headway(600.0),
86 );
87 }
88}