zen-expression 0.55.0

Zen Expression Language
Documentation
use crate::vm::date::duration_parser::{DurationParseError, DurationParser};
use crate::vm::date::duration_unit::DurationUnit;
use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
use rust_decimal::Decimal;
use std::ops::Neg;

#[derive(Debug, Clone, Default)]
pub(crate) struct Duration {
    pub seconds: i64,
    pub months: i32,
    pub years: i32,
}

impl Duration {
    pub fn parse(s: &str) -> Result<Self, DurationParseError> {
        DurationParser {
            iter: s.chars(),
            src: s,
            duration: Duration::default(),
        }
        .parse()
    }

    pub fn from_unit(n: Decimal, unit: DurationUnit) -> Option<Self> {
        if let Some(secs) = unit.as_secs() {
            return Some(Self {
                seconds: n.checked_mul(Decimal::from_u64(secs)?)?.to_i64()?,
                ..Default::default()
            });
        };

        match unit {
            DurationUnit::Month => Some(Duration {
                months: n.to_i32()?,
                ..Default::default()
            }),
            DurationUnit::Quarter => Some(Duration {
                months: n.to_i32()? * 3,
                ..Default::default()
            }),
            DurationUnit::Year => Some(Duration {
                years: n.to_i32()?,
                ..Default::default()
            }),
            _ => None,
        }
    }

    pub fn negate(self) -> Self {
        Self {
            years: self.years.neg(),
            months: self.months.neg(),
            seconds: self.seconds.neg(),
        }
    }

    pub fn day() -> Self {
        Self {
            seconds: DurationUnit::Day.as_secs().unwrap_or_default() as i64,
            ..Default::default()
        }
    }
}