Skip to content

Commit

Permalink
Merge pull request #53 from esheppa/use-systemtime
Browse files Browse the repository at this point in the history
switch from time to systemtime
  • Loading branch information
dylanhart authored Jul 30, 2022
2 parents 96aa617 + b44d1f0 commit 1e30316
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 63 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ jobs:
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
- run: cargo check --package ulid-cli
- run: cargo test
- run: cargo test --all-features
- run: cargo test --no-default-features --features=std
Expand Down
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@ repository = "https://github.com/dylanhart/ulid-rs"

[features]
default = ["std"]
std = ["rand", "time"]
std = ["rand"]

[dependencies]
serde = { version = "1.0", features = ["derive"], optional = true }
rand = { version = "0.8", optional = true }
# -- Sync versions with the WASM target below --
time = { version = "0.3", optional = true }
uuid = { version = "1.1", optional = true }

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ assert_eq!(ulid, res.unwrap());

## Crate Features

* **`std` (default)**: Flag to toggle use of `std`, `rand`, and `time`. Disable this flag for `#[no_std]` support.
* **`std` (default)**: Flag to toggle use of `std` and `rand`. Disable this flag for `#[no_std]` support.
* **`serde`**: Enables serialization and deserialization of `Ulid` types via `serde`. ULIDs are serialized using their canonical 26-character representation as defined in the ULID standard. An optional `ulid_as_u128` module is provided, which enables serialization through an `Ulid`'s inner `u128` primitive type. See the [documentation][serde_mod] and [serde docs][serde_docs] for more information.
* **`uuid`**: Implements infallible conversions between ULIDs and UUIDs from the [`uuid`][uuid] crate via the [`std::convert::From`][trait_from] trait.

Expand Down
6 changes: 3 additions & 3 deletions benches/bench.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use bencher::{benchmark_group, benchmark_main, Bencher};
use time::OffsetDateTime;
use std::time::SystemTime;
use ulid::{Generator, Ulid, ULID_LEN};

fn bench_new(b: &mut Bencher) {
b.iter(|| Ulid::new());
b.iter(Ulid::new);
}

fn bench_generator_generate(b: &mut Bencher) {
Expand All @@ -12,7 +12,7 @@ fn bench_generator_generate(b: &mut Bencher) {
}

fn bench_from_time(b: &mut Bencher) {
let time = OffsetDateTime::now_utc();
let time = SystemTime::now();
b.iter(|| Ulid::from_datetime(time));
}

Expand Down
1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ edition = "2018"
[dependencies]
structopt = "0.2"
ulid = { version = "*", path = ".." }
time = "0.3.11"
4 changes: 2 additions & 2 deletions cli/src/bin/ulid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn generate(count: u32, monotonic: bool) {

fn inspect(values: &[String]) {
for val in values {
let ulid = Ulid::from_string(&val);
let ulid = Ulid::from_string(val);
match ulid {
Ok(ulid) => {
let upper_hex = format!("{:X}", ulid.0);
Expand All @@ -81,7 +81,7 @@ COMPONENTS:
",
ulid.to_string(),
upper_hex,
ulid.datetime(),
time::OffsetDateTime::from(ulid.datetime()),
ulid.timestamp_ms(),
upper_hex.chars().skip(6).collect::<String>()
);
Expand Down
38 changes: 20 additions & 18 deletions src/generator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use time::OffsetDateTime;
use std::time::{Duration, SystemTime};

use std::fmt;

Expand Down Expand Up @@ -42,7 +42,7 @@ impl Generator {
/// assert!(ulid1 < ulid2);
/// ```
pub fn generate(&mut self) -> Result<Ulid, MonotonicError> {
let now = OffsetDateTime::now_utc();
let now = SystemTime::now();
self.generate_from_datetime(now)
}

Expand All @@ -53,9 +53,9 @@ impl Generator {
/// # Example
/// ```rust
/// use ulid::Generator;
/// use time::OffsetDateTime;
/// use std::time::SystemTime;
///
/// let dt = OffsetDateTime::now_utc();
/// let dt = SystemTime::now();
/// let mut gen = Generator::new();
///
/// let ulid1 = gen.generate_from_datetime(dt).unwrap();
Expand All @@ -64,10 +64,7 @@ impl Generator {
/// assert_eq!(ulid1.datetime(), ulid2.datetime());
/// assert!(ulid1 < ulid2);
/// ```
pub fn generate_from_datetime(
&mut self,
datetime: OffsetDateTime,
) -> Result<Ulid, MonotonicError> {
pub fn generate_from_datetime(&mut self, datetime: SystemTime) -> Result<Ulid, MonotonicError> {
self.generate_from_datetime_with_source(datetime, &mut rand::thread_rng())
}

Expand All @@ -79,7 +76,7 @@ impl Generator {
/// ```rust
/// use ulid::Generator;
/// use ulid::Ulid;
/// use time::OffsetDateTime;
/// use std::time::SystemTime;
/// use rand::prelude::*;
///
/// let mut rng = StdRng::from_entropy();
Expand All @@ -94,7 +91,7 @@ impl Generator {
where
R: rand::Rng,
{
let now = OffsetDateTime::now_utc();
let now = SystemTime::now();
self.generate_from_datetime_with_source(now, source)
}

Expand All @@ -105,10 +102,10 @@ impl Generator {
/// # Example
/// ```rust
/// use ulid::Generator;
/// use time::OffsetDateTime;
/// use std::time::SystemTime;
/// use rand::prelude::*;
///
/// let dt = OffsetDateTime::now_utc();
/// let dt = SystemTime::now();
/// let mut rng = StdRng::from_entropy();
/// let mut gen = Generator::new();
///
Expand All @@ -120,16 +117,21 @@ impl Generator {
/// ```
pub fn generate_from_datetime_with_source<R>(
&mut self,
datetime: OffsetDateTime,
datetime: SystemTime,
source: &mut R,
) -> Result<Ulid, MonotonicError>
where
R: rand::Rng,
{
let last_ms = self.previous.timestamp_ms() as i128;
let last_ms = self.previous.timestamp_ms();
// maybe time went backward, or it is the same ms.
// increment instead of generating a new random so that it is monotonic
if (datetime.unix_timestamp_nanos() / 1_000_000) <= last_ms {
if datetime
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap_or(Duration::ZERO)
.as_millis()
<= u128::from(last_ms)
{
if let Some(next) = self.previous.increment() {
self.previous = next;
return Ok(next);
Expand Down Expand Up @@ -170,15 +172,15 @@ impl fmt::Display for MonotonicError {
#[cfg(test)]
mod tests {
use super::*;
use ::time::Duration;
use std::time::Duration;

#[test]
fn test_order_monotonic() {
let dt = OffsetDateTime::now_utc();
let dt = SystemTime::now();
let mut gen = Generator::new();
let ulid1 = gen.generate_from_datetime(dt).unwrap();
let ulid2 = gen.generate_from_datetime(dt).unwrap();
let ulid3 = Ulid::from_datetime(dt + Duration::milliseconds(1));
let ulid3 = Ulid::from_datetime(dt + Duration::from_millis(1));
assert_eq!(ulid1.0 + 1, ulid2.0);
assert!(ulid2 < ulid3);
assert!(ulid2.timestamp_ms() < ulid3.timestamp_ms())
Expand Down
10 changes: 5 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ struct ReadMeDoctest;

mod base32;
#[cfg(feature = "std")]
mod time;
#[cfg(feature = "std")]
mod generator;
#[cfg(feature = "serde")]
pub mod serde;
#[cfg(feature = "std")]
mod time;
#[cfg(feature = "uuid")]
mod uuid;

Expand Down Expand Up @@ -145,13 +145,13 @@ impl Ulid {
/// # Example
/// ```rust
/// # #[cfg(feature = "std")] {
/// use ::time::OffsetDateTime;
/// use std::time::{SystemTime, Duration};
/// use ulid::Ulid;
///
/// let dt = OffsetDateTime::now_utc();
/// let dt = SystemTime::now();
/// let ulid = Ulid::from_datetime(dt);
///
/// assert_eq!(ulid.timestamp_ms(), (dt.unix_timestamp_nanos() / 1_000_000) as u64);
/// assert_eq!(u128::from(ulid.timestamp_ms()), dt.duration_since(SystemTime::UNIX_EPOCH).unwrap_or(Duration::ZERO).as_millis());
/// # }
/// ```
pub const fn timestamp_ms(&self) -> u64 {
Expand Down
Loading

0 comments on commit 1e30316

Please sign in to comment.