-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #54 from badboy/feature/mod
little bit of spring cleaning: split the large lib.rs into several files
- Loading branch information
Showing
6 changed files
with
355 additions
and
327 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use alloc::string::String; | ||
use core::str::FromStr; | ||
|
||
use crate::parsers; | ||
|
||
/// A date, can hold three different formats. | ||
/// ``` | ||
/// # use std::str::FromStr; | ||
/// assert_eq!( | ||
/// iso8601::Date::from_str("2023-02-18T17:08:08.793Z"), | ||
/// Ok(iso8601::Date::YMD{ year: 2023, month: 2, day: 18}) | ||
/// ) | ||
/// ``` | ||
#[allow(missing_docs)] | ||
#[derive(Eq, PartialEq, Debug, Copy, Clone)] | ||
pub enum Date { | ||
/// consists of year, month and day of month | ||
YMD { year: i32, month: u32, day: u32 }, | ||
/// consists of year, week and day of week | ||
Week { year: i32, ww: u32, d: u32 }, | ||
/// consists of year and day of year | ||
Ordinal { year: i32, ddd: u32 }, | ||
} | ||
|
||
impl Default for Date { | ||
fn default() -> Date { | ||
Date::YMD { | ||
year: 0, | ||
month: 0, | ||
day: 0, | ||
} | ||
} | ||
} | ||
|
||
impl FromStr for Date { | ||
type Err = String; | ||
|
||
fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
date(s) | ||
} | ||
} | ||
|
||
/// Parses a date string. | ||
/// | ||
/// A string can have one of the following formats: | ||
/// | ||
/// * `2015-11-02` or `20151102` | ||
/// * `2015-W45-01` or `2015W451` | ||
/// * `2015-306` or `2015306` | ||
/// | ||
/// ## Example | ||
/// | ||
/// ```rust | ||
/// let date = iso8601::date("2015-11-02").unwrap(); | ||
/// ``` | ||
pub fn date(string: &str) -> Result<Date, String> { | ||
if let Ok((_, parsed)) = parsers::parse_date(string.as_bytes()) { | ||
Ok(parsed) | ||
} else { | ||
Err(format!("Failed to parse date: {}", string)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
use alloc::string::String; | ||
use core::str::FromStr; | ||
|
||
use crate::{parsers, Date, Time}; | ||
|
||
/// Compound struct, holds Date and Time. | ||
/// ``` | ||
/// # use std::str::FromStr; | ||
/// assert_eq!( | ||
/// iso8601::DateTime::from_str("2023-02-18T17:08:08.793Z"), | ||
/// Ok(iso8601::DateTime { | ||
/// date: iso8601::Date::YMD{ year: 2023, month: 2, day: 18}, | ||
/// time: iso8601::Time{ hour: 17, minute: 8, second: 8, millisecond: 793, tz_offset_hours: 0, tz_offset_minutes: 00 } | ||
/// }) | ||
/// ) | ||
/// ``` | ||
#[derive(Eq, PartialEq, Debug, Copy, Clone, Default)] | ||
pub struct DateTime { | ||
/// The date part | ||
pub date: Date, | ||
/// The time part | ||
pub time: Time, | ||
} | ||
|
||
impl FromStr for DateTime { | ||
type Err = String; | ||
|
||
fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
datetime(s) | ||
} | ||
} | ||
|
||
/// Parses a datetime string. | ||
/// | ||
/// A datetime string is a combination of the valid formats for the date and time, | ||
/// separated by a literal `T`. | ||
/// See the respective functions for the correct format. | ||
/// | ||
/// ## Example | ||
/// | ||
/// ```rust | ||
/// let dt = iso8601::datetime("2015-11-03T21:56").unwrap(); | ||
/// ``` | ||
pub fn datetime(string: &str) -> Result<DateTime, String> { | ||
if let Ok((_left_overs, parsed)) = parsers::parse_datetime(string.as_bytes()) { | ||
Ok(parsed) | ||
} else { | ||
Err(format!("Failed to parse datetime: {}", string)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
use core::str::FromStr; | ||
|
||
use alloc::string::String; | ||
|
||
use crate::parsers; | ||
|
||
/// A time duration. | ||
/// Durations: | ||
/// <https://www.rfc-editor.org/rfc/rfc3339#page-13> | ||
/// dur-second = 1*DIGIT "S" | ||
/// dur-minute = 1*DIGIT "M" [dur-second] | ||
/// dur-hour = 1*DIGIT "H" [dur-minute] | ||
/// dur-time = "T" (dur-hour / dur-minute / dur-second) | ||
/// dur-day = 1*DIGIT "D" | ||
/// dur-week = 1*DIGIT "W" | ||
/// dur-month = 1*DIGIT "M" [dur-day] | ||
/// dur-year = 1*DIGIT "Y" [dur-month] | ||
/// dur-date = (dur-day / dur-month / dur-year) [dur-time] | ||
/// duration = "P" (dur-date / dur-time / dur-week) | ||
/// ``` | ||
///# use std::str::FromStr; | ||
/// assert_eq!(iso8601::Duration::from_str("P2021Y11M16DT23H26M59.123S"), Ok(iso8601::Duration::YMDHMS{ year: 2021, month: 11, day: 16, hour: 23, minute: 26, second: 59, millisecond: 123 })) | ||
/// ``` | ||
#[derive(Eq, PartialEq, Debug, Copy, Clone)] | ||
pub enum Duration { | ||
/// A duration specified by year, month, day, hour, minute and second units | ||
YMDHMS { | ||
/// Number of calendar years | ||
year: u32, | ||
/// Number of months | ||
month: u32, | ||
/// Number of days | ||
day: u32, | ||
/// Number of hours | ||
hour: u32, | ||
/// Number of minutes | ||
minute: u32, | ||
/// Number of seconds | ||
second: u32, | ||
/// Number of milliseconds | ||
millisecond: u32, | ||
}, | ||
/// consists of week units | ||
Weeks(u32), | ||
} | ||
|
||
impl Duration { | ||
/// Whether this duration represents a zero duration. | ||
pub fn is_zero(&self) -> bool { | ||
*self | ||
== Duration::YMDHMS { | ||
year: 0, | ||
month: 0, | ||
day: 0, | ||
hour: 0, | ||
minute: 0, | ||
second: 0, | ||
millisecond: 0, | ||
} | ||
|| *self == Duration::Weeks(0) | ||
} | ||
} | ||
|
||
impl Default for Duration { | ||
fn default() -> Duration { | ||
Duration::YMDHMS { | ||
year: 0, | ||
month: 0, | ||
day: 0, | ||
hour: 0, | ||
minute: 0, | ||
second: 0, | ||
millisecond: 0, | ||
} | ||
} | ||
} | ||
|
||
impl FromStr for Duration { | ||
type Err = String; | ||
|
||
fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
duration(s) | ||
} | ||
} | ||
|
||
impl From<Duration> for ::core::time::Duration { | ||
fn from(duration: Duration) -> Self { | ||
match duration { | ||
Duration::YMDHMS { | ||
year, | ||
month, | ||
day, | ||
hour, | ||
minute, | ||
second, | ||
millisecond, | ||
} => { | ||
let secs = u64::from(year) * 365 * 86_400 | ||
+ u64::from(month) * 30 * 86_400 | ||
+ u64::from(day) * 86_400 | ||
+ u64::from(hour) * 3600 | ||
+ u64::from(minute) * 60 | ||
+ u64::from(second); | ||
let nanos = millisecond * 1_000_000; | ||
Self::new(secs, nanos) | ||
} | ||
Duration::Weeks(week) => { | ||
let secs = u64::from(week) * 7 * 86_400; | ||
Self::from_secs(secs) | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// Parses a duration string. | ||
/// | ||
/// A string starts with `P` and can have one of the following formats: | ||
/// | ||
/// * Fully-specified duration: `P1Y2M3DT4H5M6S` | ||
/// * Duration in weekly intervals: `P1W` | ||
/// * Fully-specified duration in [`DateTime`](`crate::DateTime`) format: `P<datetime>` | ||
/// | ||
/// Both fully-specified formats get parsed into the YMDHMS Duration variant. | ||
/// The weekly interval format gets parsed into the Weeks Duration variant. | ||
/// | ||
/// The ranges for each of the individual units are not expected to exceed | ||
/// the next largest unit. | ||
/// | ||
/// These ranges (inclusive) are as follows: | ||
/// | ||
/// * Year (any valid u32) | ||
/// * Month 0 - 12 | ||
/// * Week 0 - 52 | ||
/// * Day 0 - 31 | ||
/// * Hour 0 - 24 | ||
/// * Minute 0 - 60 | ||
/// * Second 0 - 60 | ||
/// | ||
/// ## Examples | ||
/// | ||
/// ```rust | ||
/// let duration = iso8601::duration("P1Y2M3DT4H5M6S").unwrap(); | ||
/// let duration = iso8601::duration("P1W").unwrap(); | ||
/// let duration = iso8601::duration("P2015-11-03T21:56").unwrap(); | ||
/// ``` | ||
pub fn duration(string: &str) -> Result<Duration, String> { | ||
if let Ok((_left_overs, parsed)) = parsers::parse_duration(string.as_bytes()) { | ||
Ok(parsed) | ||
} else { | ||
Err(format!("Failed to parse duration: {}", string)) | ||
} | ||
} |
Oops, something went wrong.