Skip to content

Commit

Permalink
release: 0.2.4
Browse files Browse the repository at this point in the history
  • Loading branch information
joshstoik1 committed Jul 19, 2021
2 parents 9671c2d + a851c18 commit 7a70bbb
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 28 deletions.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "utc2k"
version = "0.2.3"
version = "0.2.4"
authors = ["Blobfolio, LLC. <[email protected]>"]
edition = "2018"
description = "A fast and lean UTC date/time library concerned only with happenings in this century (2000-2099)."
Expand All @@ -21,6 +21,7 @@ brunch = "0.1.*"
rand = "0.8.*"
serde = "1.0.*"
serde_json = "1.0.*"
serde_yaml = "0.8.*"

[dev-dependencies.chrono]
version = "0.4.*"
Expand All @@ -29,6 +30,7 @@ features = [ "std" ]

[dependencies.serde]
version = "1.0.*"
features = [ "derive" ]
optional = true

[[bench]]
Expand Down
184 changes: 157 additions & 27 deletions src/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ macro_rules! try_from_unixtime {
/// or unix timestamps. Using this enum as an intermediate step seems to be the
/// best way to achieve that.
enum RawSerde<'a> {
Str(&'a str),
Str(std::borrow::Cow<'a, str>),
Num(u32),
}

Expand Down Expand Up @@ -412,18 +412,6 @@ impl FmtUtc2k {



#[cfg(any(test, feature = "serde"))]
impl serde::Serialize for FmtUtc2k {
#[inline]
/// # Serialize.
///
/// Use the optional `serde` crate feature to enable serialization support.
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer {
self.as_str().serialize(serializer)
}
}

#[cfg(any(test, feature = "serde"))]
impl<'de> serde::Deserialize<'de> for FmtUtc2k {
/// # Deserialize.
Expand All @@ -432,12 +420,24 @@ impl<'de> serde::Deserialize<'de> for FmtUtc2k {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::de::Deserializer<'de> {
match RawSerde::deserialize(deserializer)? {
RawSerde::Str(s) => Self::try_from(s).map_err(|_| serde::de::Error::custom("Invalid date string.")),
RawSerde::Str(s) => Self::try_from(s.as_ref()).map_err(|_| serde::de::Error::custom("Invalid date string.")),
RawSerde::Num(d) => Ok(Self::from(d)),
}
}
}

#[cfg(any(test, feature = "serde"))]
impl serde::Serialize for FmtUtc2k {
#[inline]
/// # Serialize.
///
/// Use the optional `serde` crate feature to enable serialization support.
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer {
self.as_str().serialize(serializer)
}
}



#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
Expand Down Expand Up @@ -704,6 +704,36 @@ impl Utc2k {
///
/// Create a new instance representing the current UTC time.
pub fn now() -> Self { Self::from(unixtime()) }

#[inline]
#[must_use]
/// # Tomorrow.
///
/// Create a new instance representing one day from now (present time).
///
/// ## Examples
///
/// ```
/// use utc2k::Utc2k;
///
/// assert_eq!(Utc2k::tomorrow(), Utc2k::now() + 86_400_u32);
/// ```
pub fn tomorrow() -> Self { Self::from(unixtime() + DAY_IN_SECONDS) }

#[inline]
#[must_use]
/// # Yesterday.
///
/// Create a new instance representing one day ago (present time).
///
/// ## Examples
///
/// ```
/// use utc2k::Utc2k;
///
/// assert_eq!(Utc2k::yesterday(), Utc2k::now() - 86_400_u32);
/// ```
pub fn yesterday() -> Self { Self::from(unixtime() - DAY_IN_SECONDS) }
}

/// ## String Parsing.
Expand Down Expand Up @@ -987,6 +1017,37 @@ impl Utc2k {
LEAP_YEARS[self.y as usize]
}

#[must_use]
/// # Abbreviated Month Name.
///
/// Return the abbreviated name of the month, nice and pretty.
///
/// ## Examples
///
/// ```
/// use utc2k::Utc2k;
/// use std::convert::TryFrom;
///
/// let date = Utc2k::try_from("2020-06-24 20:19:30").unwrap();
/// assert_eq!(date.month_abbreviation(), "Jun");
/// ```
pub const fn month_abbreviation(self) -> &'static str {
match self.m {
1 => "Jan",
2 => "Feb",
3 => "Mar",
4 => "Apr",
5 => "May",
6 => "Jun",
7 => "Jul",
8 => "Aug",
9 => "Sep",
10 => "Oct",
11 => "Nov",
_ => "Dec",
}
}

#[must_use]
/// # Month Name.
///
Expand Down Expand Up @@ -1183,6 +1244,27 @@ impl Utc2k {
if 2 < self.m && self.leap_year() { time + DAY_IN_SECONDS }
else { time }
}

#[must_use]
/// # Change Time.
///
/// Return a new [`Utc2k`] instance with the original date — unless there
/// is carry-over needed — and a new time.
///
/// ## Examples
///
/// ```
/// use utc2k::Utc2k;
///
/// let date = Utc2k::default();
/// assert_eq!(date.to_string(), "2000-01-01 00:00:00");
///
/// // Change the time bits.
/// assert_eq!(date.with_time(13, 14, 15).to_string(), "2000-01-01 13:14:15");
/// ```
pub fn with_time(self, hh: u8, mm: u8, ss: u8) -> Self {
Self::from(Abacus::new(self.year(), self.month(), self.day(), hh, mm, ss))
}
}

/// ## Checked Operations.
Expand Down Expand Up @@ -1278,18 +1360,6 @@ impl From<Utc2k> for u32 {



#[cfg(any(test, feature = "serde"))]
impl serde::Serialize for Utc2k {
#[inline]
/// # Serialize.
///
/// Use the optional `serde` crate feature to enable serialization support.
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer {
self.unixtime().serialize(serializer)
}
}

#[cfg(any(test, feature = "serde"))]
impl<'de> serde::Deserialize<'de> for Utc2k {
/// # Deserialize.
Expand All @@ -1298,12 +1368,24 @@ impl<'de> serde::Deserialize<'de> for Utc2k {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::de::Deserializer<'de> {
match RawSerde::deserialize(deserializer)? {
RawSerde::Str(s) => Self::try_from(s).map_err(|_| serde::de::Error::custom("Invalid date string.")),
RawSerde::Str(s) => Self::try_from(s.as_ref()).map_err(|_| serde::de::Error::custom("Invalid date string.")),
RawSerde::Num(d) => Ok(Self::from(d)),
}
}
}

#[cfg(any(test, feature = "serde"))]
impl serde::Serialize for Utc2k {
#[inline]
/// # Serialize.
///
/// Use the optional `serde` crate feature to enable serialization support.
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer {
self.unixtime().serialize(serializer)
}
}



#[allow(clippy::cast_possible_truncation)] // It fits.
Expand Down Expand Up @@ -1549,6 +1631,9 @@ mod tests {
const DATENUM: &str = "1625743996";
const DATESTR_Q: &str = "\"2021-07-08 11:33:16\"";

const YSERIALNUM: &str = "---\n1625743996\n";
const YSERIALSTR: &str = "---\n\"2021-07-08 11:33:16\"\n";

{
// Formatted Version.
let date = FmtUtc2k::try_from(DATESTR).unwrap();
Expand All @@ -1564,6 +1649,29 @@ mod tests {
date2 = serde_json::from_str(DATENUM)
.expect("FmtUtc2k deserialization (u32) failed.");
assert_eq!(date, date2);

// Try it with serde_yaml, which is a bit stricter.
date2 = serde_yaml::from_str(&serial)
.expect("FmtUtc2k deserialization (str) failed.");
assert_eq!(date, date2);

date2 = serde_yaml::from_str(DATENUM)
.expect("FmtUtc2k deserialization (u32) failed.");
assert_eq!(date, date2);

// Serialize it with serde_yaml too.
let serial2 = serde_yaml::to_string(&date)
.expect("FmtUtc2k serialization failed.");
assert_eq!(serial2, YSERIALSTR);

// And make sure deserialization from YAML format works.
date2 = serde_yaml::from_str(YSERIALSTR)
.expect("FmtUtc2k deserialization (str) failed.");
assert_eq!(date, date2);

date2 = serde_yaml::from_str(YSERIALNUM)
.expect("FmtUtc2k deserialization (u32) failed.");
assert_eq!(date, date2);
}

{
Expand All @@ -1581,6 +1689,28 @@ mod tests {
date2 = serde_json::from_str(DATESTR_Q)
.expect("Utc2k deserialization (str) failed.");
assert_eq!(date, date2);

// Again, retry with serde_yaml.
date2 = serde_yaml::from_str(&serial)
.expect("Utc2k deserialization (u32) failed.");
assert_eq!(date, date2);

// We should also be able to deserialize from a datetime string.
date2 = serde_yaml::from_str(DATESTR_Q)
.expect("Utc2k deserialization (str) failed.");
assert_eq!(date, date2);

let serial2 = serde_yaml::to_string(&date)
.expect("Utc2k serialization failed.");
assert_eq!(serial2, YSERIALNUM);

date2 = serde_yaml::from_str(YSERIALSTR)
.expect("Utc2k deserialization (str) failed.");
assert_eq!(date, date2);

date2 = serde_yaml::from_str(YSERIALNUM)
.expect("Utc2k deserialization (u32) failed.");
assert_eq!(date, date2);
}
}
}

0 comments on commit 7a70bbb

Please sign in to comment.