pub struct Span {
pub seconds: u64,
}Expand description
Timespan (Duration)
Simply an unsigned count of seconds.
Debug, Display and FromStr implementations break this number, which is often incomprehensibly large, down into understandable units.
So instead of Span { seconds: 108030 } you get 1d6h30s.
These are the units used:
Scale | unit | seconds |
|---|---|---|
| Years | y | 31556952 |
| Months | mo | 2629746 |
| Weeks | w | 604800 |
| Days | d | 86400 |
| Hours | h | 3600 |
| Minutes | m | 60 |
| Seconds | s | 1 |
As explained in the documentation for Scale, the amount of seconds for y and mo is the average for each of these scales.
The Span can be parsed from the terse duration format using parse or try_parse.
These methods are also const, so they can be used to define constants.
use greg::Span;
const TIMEOUT: Span = Span::parse("30s");
assert_eq!(Span::parse("0s"), Span::from_seconds(0));
assert_eq!(Span::parse("1m30s"), Span::MINUTE + Span::SECOND * 30);
assert_eq!(Span::parse("1d10h"), Span::DAY + Span::HOUR * 10);
assert_eq!(Span::try_parse("48h"), Ok(Span::DAY * 2));
assert_eq!(
Span::parse("3w2h10m30s"),
Span::WEEK * 3 + Span::HOUR * 2 + Span::MINUTE * 10 + Span::SECOND * 30
);The alternate form for Display (with {:#}) produces a string where each number/unit pair is separated by a space.
Additionally, if a precision is specified (with {:.2}), at most the requested number of number/unit pairs are printed, truncating smaller units.
use greg::Span;
let span = Span::parse("1w2d8h33m12s");
assert_eq!(span.to_string(), "1w2d8h33m12s");
assert_eq!(format!("{span:#}"), "1w 2d 8h 33m 12s");
assert_eq!(format!("{span:#.2}"), "1w 2d");Fields§
§seconds: u64Duration in seconds
Implementations§
Source§impl Span
impl Span
Sourcepub const fn from_seconds(seconds: u64) -> Self
pub const fn from_seconds(seconds: u64) -> Self
Same as constructing Span {seconds} directly
Source§impl Span
impl Span
Sourcepub const fn checked_add(self, other: Self) -> Option<Self>
pub const fn checked_add(self, other: Self) -> Option<Self>
Checked addition: computes self + other, returning None if overflow occurred.
Sourcepub const fn checked_sub(self, other: Self) -> Option<Self>
pub const fn checked_sub(self, other: Self) -> Option<Self>
Checked subtraction: computes self - other, returning None if overflow occurred.
Sourcepub const fn saturating_add(self, other: Self) -> Self
pub const fn saturating_add(self, other: Self) -> Self
Saturating addition: computes self + other, saturating at the numeric bounds instead of overflowing.
Sourcepub const fn saturating_sub(self, other: Self) -> Self
pub const fn saturating_sub(self, other: Self) -> Self
Saturating subtraction: computes self - other, saturating at the numeric bounds instead of overflowing.
Sourcepub fn scale_div(self) -> (Scale, u64)
pub fn scale_div(self) -> (Scale, u64)
Break down into a Scale and count
Returns the biggest Scale that divides the Span without a remainder as well as the result of this division.
One exception is the empty Span::ZERO, because the count is 0 for every Scale.
Instead of returning (Scale::Years, 0), which would be counter-intuitive, the zero-second Span always returns the more natural (Scale::Seconds, 0).
Remember that Scale::Years and Scale::Months are special, because they represent an average, they do not cleanly divide into weeks, days or even minutes!
See the Scale documentation for details.
use greg::{Span, Scale};
assert_eq!(Span::from_seconds(600).scale_div(), (Scale::Minutes, 10));
assert_eq!(Span::ZERO.scale_div(), (Scale::Seconds, 0));
let one_and_a_half: Span = "1h30m".parse().unwrap();
assert_eq!(one_and_a_half.scale_div(), (Scale::Minutes, 90));
Source§impl Span
impl Span
Sourcepub const fn parse(from: &str) -> Self
pub const fn parse(from: &str) -> Self
Try to parse terse duration format and panic if invalid
use greg::Span;
const CHILIAD: Span = Span::parse("1000y");
assert_eq!(Span::parse("0s"), Span::ZERO);
assert_eq!(Span::parse("10s").seconds, 10);
assert_eq!(Span::parse("1m30s").seconds, 90);
let _ = Span::parse("3mo2h10m30s");This is mainly useful in const contexts, since the panic gets caught at compile-time.
use greg::Span;
const DECADE: Span = Span::parse("10t"); // typo: "t" instead of "y"Sourcepub const fn try_parse(from: &str) -> Result<Self, ParseSpanError>
pub const fn try_parse(from: &str) -> Result<Self, ParseSpanError>
Try to parse terse duration format
use greg::Span;
assert_eq!(Span::try_parse("0s"), Ok(Span::ZERO));
assert_eq!(Span::try_parse("1w"), Ok(Span::WEEK));
assert_eq!(Span::try_parse("1m30s"), Ok(Span::MINUTE + Span::SECOND * 30));
let _ = Span::try_parse("3mo2h10m30s").unwrap();
assert!(Span::try_parse("10 hours").is_err(), "long-form units don't work");Trait Implementations§
Source§impl<'de> Deserialize<'de> for Span
Available on crate feature serde only.
impl<'de> Deserialize<'de> for Span
serde only.Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Source§impl FromSql for Span
Available on crate feature rusqlite only.
impl FromSql for Span
rusqlite only.Source§fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self>
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self>
Source§impl Ord for Span
impl Ord for Span
Source§impl PartialOrd for Span
impl PartialOrd for Span
Source§impl ToSql for Span
Available on crate feature rusqlite only.
impl ToSql for Span
rusqlite only.