Struct fundu::CustomTimeUnit

source ·
pub struct CustomTimeUnit<'a> { /* private fields */ }
Available on crate feature custom only.
Expand description

A CustomTimeUnit is a completely customizable TimeUnit using an additional Multiplier.

Custom time units have a base TimeUnit (which has an inherent Multiplier) and an optional Multiplier which acts as an additional Multiplier to the multiplier of the base_unit. Using a multiplier with Multiplier(1, 0) is equivalent to using no multiplier at all but see also the Problems section. A CustomTimeUnit also consists of identifiers which are used to identify the CustomTimeUnit during the parsing process.

To create a CustomTimeUnit representing two weeks there are multiple solutions. Just to show two very obvious examples:

use fundu::TimeUnit::*;
use fundu::{CustomTimeUnit, Multiplier};

assert_ne!(
    (CustomTimeUnit::new(Week, &["fortnight", "fortnights"], Some(Multiplier(2, 0)))),
    (CustomTimeUnit::new(Day, &["fortnight", "fortnights"], Some(Multiplier(14, 0))))
);

Both would actually be equal in the sense, that they would resolve to the same result when multiplying the base_unit with the multiplier, however they are treated as not equal and it’s possible to choose freely between the definitions. Using both of the definitions in parallel within the crate::CustomDurationParser would be possible and produces the desired result, although it does not provide any benefits.

use std::time::Duration;

use fundu::TimeUnit::*;
use fundu::{CustomDurationParser, CustomTimeUnit, Multiplier};

let parser = CustomDurationParser::builder()
    .custom_time_units(&[
        CustomTimeUnit::new(Week, &["fortnight", "fortnights"], Some(Multiplier(2, 0))),
        CustomTimeUnit::new(Day, &["fortnight", "fortnights"], Some(Multiplier(14, 0))),
    ])
    .build();

assert_eq!(
    parser.parse("1fortnight").unwrap(),
    Duration::new(1209600, 0)
);

In summary, the best choice is to use the CustomTimeUnit with a base_unit having the lowest Multiplier but see also Problems below.

Equality of two CustomTimeUnit is defined as

base_unit == other.base_unit && multiplier == other.multiplier

Problems

For base_units other than Second there may occur an overflow (and panic) during the parsing process. The Multiplier boundaries are chosen as high as possible but if the base_unit multiplier multiplied with multiplier exceeds (u64::MAX, i16::MIN) or (u64::MAX, i16::MAX) this multiplication overflows. By example, with Multiplier(m, e) two multipliers x, y are multiplied as follows : m = x.m * y.m, e = x.e + y.e:

If the base_unit is Year, which has a multiplier of m = 31557600, e = 0, then this restricts the multiplier to m = u64::MAX / 31557600 = 584_542_046_090, e = 32767 or e = -32768.

If the base_unit is NanoSecond, which has a multiplier of m = 1, e = -9, then this restricts the multiplier to m = u64::MAX, e = -32768 + 9 = -32,759 or e = i16::MAX = 32767.

The base_units are Seconds based what results in the following table with limits for the multiplier:

base_unitMultiplierLimit mLimit -eLimit +e
NanosecondMultiplier(1, -9)u64::MAX-32,759i16::MAX
MicrosecondMultiplier(1, -6)u64::MAX-32,762i16::MAX
MillisecondMultiplier(1, -3)u64::MAX-32,765i16::MAX
SecondMultiplier(1, 0)u64::MAXi16::MINi16::MAX
MinuteMultiplier(60, 0)307_445_734_561_825_860i16::MINi16::MAX
HourMultiplier(3600, 0)5_124_095_576_030_431i16::MINi16::MAX
DayMultiplier(86400, 0)213_503_982_334_601i16::MINi16::MAX
WeekMultiplier(604800, 0)30_500_568_904_943i16::MINi16::MAX
MonthMultiplier(2629800, 0)7_014_504_553_087i16::MINi16::MAX
YearMultiplier(31557600, 0)584_542_046_090i16::MINi16::MAX

Implementations§

source§

impl<'a> CustomTimeUnit<'a>

source

pub const fn new( base_unit: TimeUnit, identifiers: &'a [&'a str], multiplier: Option<Multiplier> ) -> Self

Create a new CustomTimeUnit

See also the documentation for CustomTimeUnit.

Examples
use std::time::Duration;

use fundu::TimeUnit::*;
use fundu::{CustomDurationParser, CustomTimeUnit, Multiplier};

let time_unit = CustomTimeUnit::new(Second, &["shake", "shakes"], Some(Multiplier(1, -8)));
let parser = CustomDurationParser::builder()
    .custom_time_unit(time_unit)
    .build();

assert_eq!(parser.parse("1shake").unwrap(), Duration::new(0, 10));

Trait Implementations§

source§

impl<'a> Clone for CustomTimeUnit<'a>

source§

fn clone(&self) -> CustomTimeUnit<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for CustomTimeUnit<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> PartialEq<CustomTimeUnit<'a>> for CustomTimeUnit<'a>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<'a> Copy for CustomTimeUnit<'a>

source§

impl<'a> Eq for CustomTimeUnit<'a>

source§

impl<'a> StructuralEq for CustomTimeUnit<'a>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for CustomTimeUnit<'a>

§

impl<'a> Send for CustomTimeUnit<'a>

§

impl<'a> Sync for CustomTimeUnit<'a>

§

impl<'a> Unpin for CustomTimeUnit<'a>

§

impl<'a> UnwindSafe for CustomTimeUnit<'a>

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.