diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 72b31f2..3658001 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,14 +7,14 @@ on: jobs: unit-tests: runs-on: ubuntu-latest - container: rust:1.59-alpine + container: rust:1.70-alpine steps: - uses: actions/checkout@v2 - run: apk add alpine-sdk - run: cargo test --all-features --workspace lint: runs-on: ubuntu-latest - container: rust:1.59-alpine + container: rust:1.70-alpine steps: - uses: actions/checkout@v2 - run: rustup toolchain install nightly @@ -22,7 +22,7 @@ jobs: - run: cargo +nightly fmt -- --check docs: runs-on: ubuntu-latest - container: rust:1.59-alpine + container: rust:1.70-alpine steps: - uses: actions/checkout@v2 - run: apk add alpine-sdk diff --git a/Cargo.toml b/Cargo.toml index 7eb1817..ffb6dab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "unix-ts" -version = "0.4.1" +version = "0.6.0" edition = "2021" authors = [ "Luke Sneeringer " @@ -24,7 +24,7 @@ chrono = { version = "0.4", optional = true } unix-ts-macros = { path = "macros", version = "0.4" } [dev-dependencies] -chrono-tz = "0.6" +chrono-tz = "^0.8.3" assert2 = "0.3" [build-dependencies] diff --git a/build.rs b/build.rs index 04b2406..9313a7d 100644 --- a/build.rs +++ b/build.rs @@ -3,7 +3,7 @@ use std::error::Error; use std::fs; use std::path::PathBuf; -const CRATE_NAME: &str = "plutus"; +const CRATE_NAME: &str = "unix-ts"; fn main() -> Result<(), Box> { println!("cargo:rerun-if-changed=README.md"); diff --git a/macros/Cargo.toml b/macros/Cargo.toml index da05020..87dbdc8 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -20,7 +20,7 @@ exclude = [ proc-macro = true [dev-dependencies] -unix-ts = { path = "..", version = "0.4.0" } +unix-ts = { path = "..", version = "0.6.0" } [build-dependencies] readme-rustdocifier = "0.1" diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 70fa90b..d7aa5c3 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -25,7 +25,7 @@ use proc_macro::TokenStream; #[proc_macro] pub fn ts(input: TokenStream) -> TokenStream { let mut src = input.to_string().trim_start().trim_end().to_owned(); - if src.len() == 0 { + if src.is_empty() { panic!("No input to ts! macro."); } @@ -73,12 +73,12 @@ pub fn ts(input: TokenStream) -> TokenStream { } // Return the new timestamp. - return format!( + format!( "::unix_ts::Timestamp::new({}{}, {})", if neg { '-' } else { ' ' }, seconds, - nanos[0..9].to_string(), + &nanos[0..9], ) .parse() - .unwrap(); + .expect("Not a number.") } diff --git a/src/chrono.rs b/src/chrono.rs index 0481223..6475c5f 100644 --- a/src/chrono.rs +++ b/src/chrono.rs @@ -1,9 +1,8 @@ -extern crate chrono; - use chrono::DateTime; use chrono::NaiveDateTime; use chrono::TimeZone; use chrono::Utc; +use std::fmt::Display; use crate::timestamp::Timestamp; diff --git a/src/display.rs b/src/display.rs new file mode 100644 index 0000000..d60d9cb --- /dev/null +++ b/src/display.rs @@ -0,0 +1,26 @@ +use std::fmt::Display; + +use crate::Timestamp; + +impl Display for Timestamp { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match f.precision() { + Some(p) => { + let float = self.seconds as f64 + self.nanos as f64 / 1_000_000_000.0; + write!(f, "{:.*}", p, float) + } + None => write!(f, "{}", self.seconds), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_display() { + let t = Timestamp::from(1335020400); + assert_eq!(format!("{:.02}", t), "1335020400.00"); + } +} diff --git a/src/lib.rs b/src/lib.rs index 3b57a5d..215d048 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ #![crate_name = "unix_ts"] #![doc = include_str!(concat!(env!("OUT_DIR"), "/README-rustdocified.md"))] +mod display; mod integers; mod std_duration; mod timestamp; diff --git a/src/timestamp.rs b/src/timestamp.rs index c65cbe5..5f6ac59 100644 --- a/src/timestamp.rs +++ b/src/timestamp.rs @@ -23,37 +23,36 @@ impl Timestamp { /// Note: For negative timestamps, the `nanos` argument is _always_ a /// positive offset. Therefore, the correct way to represent a timestamp /// of `-0.25 seconds` is to call `new(-1, 750_000_000)`. - pub fn new(mut seconds: i64, mut nanos: u32) -> Timestamp { + pub const fn new(mut seconds: i64, mut nanos: u32) -> Timestamp { while nanos >= 1_000_000_000 { seconds += 1; nanos -= 1_000_000_000; } - Timestamp { seconds: seconds, nanos: nanos } + Timestamp { seconds, nanos } } /// Create a timestamp from the given number of nanoseconds. - pub fn from_nanos(nanos: impl Into) -> Timestamp { - let nanos = nanos.into(); - let seconds: i64 = (nanos / 1_000_000_000) - .try_into() - .expect("Timestamp value out of range."); + pub const fn from_nanos(nanos: i128) -> Timestamp { + let seconds: i64 = (nanos / 1_000_000_000) as i64; + // .try_into() + // .expect("Timestamp value out of range."); let nanos = if seconds >= 0 { (nanos % 1_000_000_000) as u32 } else { (1_000_000_000 - (nanos % 1_000_000_000).abs()) as u32 }; - Timestamp { seconds: seconds, nanos: nanos } + Timestamp { seconds, nanos } } /// Create a timestamp from the given number of microseconds. - pub fn from_micros(micros: impl Into) -> Timestamp { - Timestamp::from_nanos(micros.into() * 1_000) + pub const fn from_micros(micros: i64) -> Timestamp { + Timestamp::from_nanos(micros as i128 * 1_000) } /// Create a timestamp from the given number of milliseconds. - pub fn from_millis(millis: impl Into) -> Timestamp { - Timestamp::from_nanos(millis.into() * 1_000_000) + pub const fn from_millis(millis: i64) -> Timestamp { + Timestamp::from_nanos(millis as i128 * 1_000_000) } /// Return the seconds since the Unix epoch. @@ -67,7 +66,7 @@ impl Timestamp { /// let t = Timestamp::from(1335020400); /// assert_eq!(t.seconds(), 1335020400); /// ``` - pub fn seconds(&self) -> i64 { + pub const fn seconds(&self) -> i64 { self.seconds } @@ -89,9 +88,9 @@ impl Timestamp { /// assert_eq!(t.at_precision(3), 1335020400_000); /// assert_eq!(t.at_precision(6), 1335020400_000_000); /// ``` - pub fn at_precision(&self, e: u8) -> i128 { - i128::from(self.seconds) * 10i128.pow(e.into()) - + i128::from(self.nanos) / 10i128.pow(9 - u32::from(e)) + pub const fn at_precision(&self, e: u8) -> i128 { + (self.seconds as i128) * 10i128.pow(e as u32) + + (self.nanos as i128) / 10i128.pow(9 - (e as u32)) } /// Return the subsecond component at the specified precision @@ -142,6 +141,7 @@ impl Sub for Timestamp { } #[cfg(test)] +#[allow(clippy::inconsistent_digit_grouping)] mod tests { use super::*; use assert2::check; @@ -160,11 +160,11 @@ mod tests { #[test] fn test_from_nanos() { check!( - Timestamp::from_nanos(1335020400_000_000_000i64) + Timestamp::from_nanos(1335020400_000_000_000i128) == Timestamp::new(1335020400, 0) ); check!( - Timestamp::from_nanos(1335020400_500_000_000i64) + Timestamp::from_nanos(1335020400_500_000_000i128) == Timestamp::new(1335020400, 500_000_000) ); check!(