use std::collections::HashMap;
use crate::label::TripContext;
use crate::{Duration, Label, RouteIdx, SecondOfDay, StopIdx};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct ArrivalAndWalk {
pub arrival: SecondOfDay,
pub walk_time: Duration,
}
impl Label for ArrivalAndWalk {
type Ctx = ();
const UNREACHED: Self = ArrivalAndWalk {
arrival: SecondOfDay::MAX,
walk_time: Duration::ZERO,
};
#[inline]
fn from_departure(_ctx: &Self::Ctx, at: SecondOfDay) -> Self {
ArrivalAndWalk {
arrival: at,
walk_time: Duration::ZERO,
}
}
#[inline]
fn extend_by_trip(self, _ctx: &Self::Ctx, leg: TripContext) -> Self {
ArrivalAndWalk {
arrival: leg.arrival,
walk_time: self.walk_time,
}
}
#[inline]
fn extend_by_footpath(
self,
_ctx: &Self::Ctx,
_from_stop: StopIdx,
_to_stop: StopIdx,
walk: Duration,
) -> Self {
ArrivalAndWalk {
arrival: self.arrival + walk,
walk_time: self.walk_time + walk,
}
}
#[inline]
fn dominates(&self, other: &Self) -> bool {
self.arrival <= other.arrival && self.walk_time <= other.walk_time
}
#[inline]
fn arrival(&self) -> SecondOfDay {
self.arrival
}
}
#[derive(Debug, Default, Clone)]
pub struct FareTable {
pub per_route: HashMap<RouteIdx, u32>,
}
impl FareTable {
#[inline]
pub fn fare_for(&self, route: RouteIdx) -> u32 {
self.per_route.get(&route).copied().unwrap_or(0)
}
}
impl FromIterator<(RouteIdx, u32)> for FareTable {
fn from_iter<I: IntoIterator<Item = (RouteIdx, u32)>>(iter: I) -> Self {
Self {
per_route: iter.into_iter().collect(),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct ArrivalAndFare {
pub arrival: SecondOfDay,
pub fare: u32,
}
impl Label for ArrivalAndFare {
type Ctx = FareTable;
const UNREACHED: Self = ArrivalAndFare {
arrival: SecondOfDay::MAX,
fare: 0,
};
#[inline]
fn from_departure(_ctx: &Self::Ctx, at: SecondOfDay) -> Self {
ArrivalAndFare {
arrival: at,
fare: 0,
}
}
#[inline]
fn extend_by_trip(self, ctx: &Self::Ctx, leg: TripContext) -> Self {
ArrivalAndFare {
arrival: leg.arrival,
fare: self.fare.saturating_add(ctx.fare_for(leg.route)),
}
}
#[inline]
fn extend_by_footpath(
self,
_ctx: &Self::Ctx,
_from_stop: StopIdx,
_to_stop: StopIdx,
walk: Duration,
) -> Self {
ArrivalAndFare {
arrival: self.arrival + walk,
fare: self.fare,
}
}
#[inline]
fn dominates(&self, other: &Self) -> bool {
self.arrival <= other.arrival && self.fare <= other.fare
}
#[inline]
fn arrival(&self) -> SecondOfDay {
self.arrival
}
}