routee-compass-core 0.7.0

The core routing algorithms and data structures of the RouteE-Compass energy-aware routing engine
Documentation
use super::{
    as_f64::AsF64, builders, internal_float::InternalFloat, Distance, DistanceUnit, SpeedUnit,
    Time, TimeUnit, UnitError,
};
use allocative::Allocative;
use derive_more::{Add, Div, Mul, Neg, Sub, Sum};
use serde::{Deserialize, Serialize};
use std::{cmp::Ordering, fmt::Display, str::FromStr};

#[derive(
    Copy,
    Clone,
    Serialize,
    Deserialize,
    PartialEq,
    Eq,
    Hash,
    Debug,
    Default,
    Add,
    Sub,
    Mul,
    Div,
    Sum,
    Neg,
    Allocative,
)]
pub struct Speed(pub InternalFloat);

impl AsF64 for Speed {
    fn as_f64(&self) -> f64 {
        (self.0).0
    }
}

impl From<(Distance, Time)> for Speed {
    fn from(value: (Distance, Time)) -> Self {
        let (distance, time) = value;
        let speed = distance.as_f64() / time.as_f64();
        Speed::new(speed)
    }
}

impl PartialOrd for Speed {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.0.cmp(&other.0))
    }
}

impl Ord for Speed {
    fn cmp(&self, other: &Self) -> Ordering {
        self.0.cmp(&other.0)
    }
}

impl Display for Speed {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{:?}", self.0)
    }
}

impl FromStr for Speed {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let value = s
            .parse::<f64>()
            .map_err(|_| format!("could not parse {} as a number", s))?;
        if value < 0.0 {
            Err(format!(
                "speed value {} invalid, must be strictly positive (0, +inf]",
                value
            ))
        } else {
            Ok(Speed::new(value))
        }
    }
}

impl Speed {
    pub fn new(value: f64) -> Speed {
        Speed(InternalFloat::new(value))
    }
    pub fn create(
        time: &Time,
        time_unit: &TimeUnit,
        distance: &Distance,
        distance_unit: &DistanceUnit,
        speed_unit: &SpeedUnit,
    ) -> Result<Speed, UnitError> {
        builders::create_speed(time, time_unit, distance, distance_unit, speed_unit)
    }
    pub fn to_f64(&self) -> f64 {
        (self.0).0
    }
    pub const ZERO: Speed = Speed(InternalFloat::ZERO);
    pub const ONE: Speed = Speed(InternalFloat::ONE);
}