use rustsim_geometry::vec3::Vec3;
use rustsim_modes::TravelMode;
use rustsim_transit::{RouteId, StopId};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Waypoint {
pub pos: Vec3,
pub floor: i32,
}
impl Waypoint {
pub fn ground(x: f64, y: f64) -> Self {
Self {
pos: [x, y, 0.0],
floor: 0,
}
}
}
#[derive(Debug, Clone)]
pub enum Leg {
Walk {
from: Waypoint,
to: Waypoint,
},
DriveSelf {
mode: TravelMode,
from: Waypoint,
to: Waypoint,
},
Hail {
mode: TravelMode,
from: Waypoint,
to: Waypoint,
},
Transit {
route: RouteId,
board_at: StopId,
alight_at: StopId,
},
Connector {
connector_id: u64,
},
}
impl Leg {
pub fn mode(&self) -> TravelMode {
match self {
Leg::Walk { .. } | Leg::Connector { .. } => TravelMode::Pedestrian,
Leg::DriveSelf { mode, .. } | Leg::Hail { mode, .. } => *mode,
Leg::Transit { .. } => TravelMode::Transit,
}
}
}
#[derive(Debug, Clone)]
pub struct TripPlan {
pub id: u64,
pub legs: Vec<Leg>,
}
impl TripPlan {
pub fn len(&self) -> usize {
self.legs.len()
}
pub fn is_empty(&self) -> bool {
self.legs.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn leg_mode_dispatch() {
let walk = Leg::Walk {
from: Waypoint::ground(0.0, 0.0),
to: Waypoint::ground(1.0, 0.0),
};
assert_eq!(walk.mode(), TravelMode::Pedestrian);
let transit = Leg::Transit {
route: 1,
board_at: 10,
alight_at: 20,
};
assert_eq!(transit.mode(), TravelMode::Transit);
let drive = Leg::DriveSelf {
mode: TravelMode::Vehicle,
from: Waypoint::ground(0.0, 0.0),
to: Waypoint::ground(5.0, 0.0),
};
assert_eq!(drive.mode(), TravelMode::Vehicle);
}
}