Struct SpanParser

struct SpanParser { ... }

A parser for Jiff's "friendly" duration format.

See the module documentation for more details on the precise format supported by this parser.

Unlike SpanPrinter, this parser doesn't have any configuration knobs. While it may grow some in the future, the approach taken here is for the parser to support the entire grammar. That is, the parser can parse anything emitted by SpanPrinter. (And indeed, the parser can even handle things that the printer can't emit due to lack of configurability. For example, 1hour1m is a valid friendly duration, but SpanPrinter cannot emit it due to a mixing of verbose and compact designator labels.)

Advice

Since this parser has no configuration, there are generally only two reasons why you might want to use this type specifically:

  1. You need to parse from &[u8].
  2. You need to parse only the "friendly" format.

Otherwise, you can use the FromStr implementations on both Span and SignedDuration, which automatically support the friendly format in addition to the ISO 8601 format simultaneously:

use jiff::{SignedDuration, Span, ToSpan};

let span: Span = "5 years, 2 months".parse()?;
assert_eq!(span, 5.years().months(2).fieldwise());

let sdur: SignedDuration = "5 hours, 2 minutes".parse()?;
assert_eq!(sdur, SignedDuration::new(5 * 60 * 60 + 2 * 60, 0));

# Ok::<(), Box<dyn std::error::Error>>(())

Example

This example shows how to parse a Span directly from &str:

use jiff::{fmt::friendly::SpanParser, ToSpan};

static PARSER: SpanParser = SpanParser::new();

let string = "1 year, 3 months, 15:00:01.3";
let span = PARSER.parse_span(string)?;
assert_eq!(
    span,
    1.year().months(3).hours(15).seconds(1).milliseconds(300).fieldwise(),
);

// Negative durations are supported too!
let string = "1 year, 3 months, 15:00:01.3 ago";
let span = PARSER.parse_span(string)?;
assert_eq!(
    span,
    -1.year().months(3).hours(15).seconds(1).milliseconds(300).fieldwise(),
);

# Ok::<(), Box<dyn std::error::Error>>(())

Implementations

impl SpanParser

const fn new() -> SpanParser

Creates a new parser for the "friendly" duration format.

The parser returned uses the default configuration. (Although, at time of writing, there are no available configuration options for this parser.) This is identical to SpanParser::default, but it can be used in a const context.

Example

This example shows how to parse a Span directly from &[u8]:

use jiff::{fmt::friendly::SpanParser, ToSpan};

static PARSER: SpanParser = SpanParser::new();

let bytes = b"1 year 3 months 15 hours 1300ms";
let span = PARSER.parse_span(bytes)?;
assert_eq!(
    span,
    1.year().months(3).hours(15).milliseconds(1300).fieldwise(),
);

# Ok::<(), Box<dyn std::error::Error>>(())
fn parse_span<I: AsRef<[u8]>>(self: &Self, input: I) -> Result<Span, Error>

Run the parser on the given string (which may be plain bytes) and, if successful, return the parsed Span.

See the module documentation for more details on the specific grammar supported by this parser.

Example

This shows a number of different duration formats that can be parsed into a Span:

use jiff::{fmt::friendly::SpanParser, ToSpan};

let spans = [
    ("40d", 40.days()),
    ("40 days", 40.days()),
    ("1y1d", 1.year().days(1)),
    ("1yr 1d", 1.year().days(1)),
    ("3d4h59m", 3.days().hours(4).minutes(59)),
    ("3 days, 4 hours, 59 minutes", 3.days().hours(4).minutes(59)),
    ("3d 4h 59m", 3.days().hours(4).minutes(59)),
    ("2h30m", 2.hours().minutes(30)),
    ("2h 30m", 2.hours().minutes(30)),
    ("1mo", 1.month()),
    ("1w", 1.week()),
    ("1 week", 1.week()),
    ("1w4d", 1.week().days(4)),
    ("1 wk 4 days", 1.week().days(4)),
    ("1m", 1.minute()),
    ("0.0021s", 2.milliseconds().microseconds(100)),
    ("0s", 0.seconds()),
    ("0d", 0.seconds()),
    ("0 days", 0.seconds()),
    (
        "1y1mo1d1h1m1.1s",
        1.year().months(1).days(1).hours(1).minutes(1).seconds(1).milliseconds(100),
    ),
    (
        "1yr 1mo 1day 1hr 1min 1.1sec",
        1.year().months(1).days(1).hours(1).minutes(1).seconds(1).milliseconds(100),
    ),
    (
        "1 year, 1 month, 1 day, 1 hour, 1 minute 1.1 seconds",
        1.year().months(1).days(1).hours(1).minutes(1).seconds(1).milliseconds(100),
    ),
    (
        "1 year, 1 month, 1 day, 01:01:01.1",
        1.year().months(1).days(1).hours(1).minutes(1).seconds(1).milliseconds(100),
    ),
    (
        "1 yr, 1 month, 1 d, 1 h, 1 min 1.1 second",
        1.year().months(1).days(1).hours(1).minutes(1).seconds(1).milliseconds(100),
    ),
];

static PARSER: SpanParser = SpanParser::new();
for (string, span) in spans {
    let parsed = PARSER.parse_span(string)?;
    assert_eq!(
        span.fieldwise(),
        parsed.fieldwise(),
        "result of parsing {string:?}",
    );
}

# Ok::<(), Box<dyn std::error::Error>>(())
fn parse_duration<I: AsRef<[u8]>>(self: &Self, input: I) -> Result<SignedDuration, Error>

Run the parser on the given string (which may be plain bytes) and, if successful, return the parsed SignedDuration.

See the module documentation for more details on the specific grammar supported by this parser.

Example

This shows a number of different duration formats that can be parsed into a SignedDuration:

use jiff::{fmt::friendly::SpanParser, SignedDuration};

let durations = [
    ("2h30m", SignedDuration::from_secs(2 * 60 * 60 + 30 * 60)),
    ("2 hrs 30 mins", SignedDuration::from_secs(2 * 60 * 60 + 30 * 60)),
    ("2 hours 30 minutes", SignedDuration::from_secs(2 * 60 * 60 + 30 * 60)),
    ("2 hrs 30 minutes", SignedDuration::from_secs(2 * 60 * 60 + 30 * 60)),
    ("2.5h", SignedDuration::from_secs(2 * 60 * 60 + 30 * 60)),
    ("1m", SignedDuration::from_mins(1)),
    ("1.5m", SignedDuration::from_secs(90)),
    ("0.0021s", SignedDuration::new(0, 2_100_000)),
    ("0s", SignedDuration::ZERO),
    ("0.000000001s", SignedDuration::from_nanos(1)),
];

static PARSER: SpanParser = SpanParser::new();
for (string, duration) in durations {
    let parsed = PARSER.parse_duration(string)?;
    assert_eq!(duration, parsed, "result of parsing {string:?}");
}

# Ok::<(), Box<dyn std::error::Error>>(())

impl Clone for SpanParser

fn clone(self: &Self) -> SpanParser

impl Debug for SpanParser

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

impl Default for SpanParser

fn default() -> SpanParser

impl Freeze for SpanParser

impl RefUnwindSafe for SpanParser

impl Send for SpanParser

impl Sync for SpanParser

impl Unpin for SpanParser

impl UnsafeUnpin for SpanParser

impl UnwindSafe for SpanParser

impl<T> Any for SpanParser

fn type_id(self: &Self) -> TypeId

impl<T> Borrow for SpanParser

fn borrow(self: &Self) -> &T

impl<T> BorrowMut for SpanParser

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

impl<T> CloneToUninit for SpanParser

unsafe fn clone_to_uninit(self: &Self, dest: *mut u8)

impl<T> From for SpanParser

fn from(t: T) -> T

Returns the argument unchanged.

impl<T> ToOwned for SpanParser

fn to_owned(self: &Self) -> T
fn clone_into(self: &Self, target: &mut T)

impl<T, U> Into for SpanParser

fn into(self: Self) -> U

Calls U::from(self).

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

impl<T, U> TryFrom for SpanParser

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

impl<T, U> TryInto for SpanParser

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