dylanhart / ulid-rs

This is a Rust implementation of the ulid project
https://crates.io/crates/ulid
MIT License
385 stars 37 forks source link

Enforce monotonicity in same millisecond #10

Closed camerondavison closed 5 years ago

camerondavison commented 5 years ago

The spec says that there will be monotonicity within the same millisecond https://github.com/ulid/spec#monotonicity

It does not looks like this is enforced currently.

dylanhart commented 5 years ago

Hi! Thank you for your contribution. You're right that this isn't currently implemented; It wasn't in the spec when this project was created. This will likely be implemented with adding a Generator/Factory struct to the library that can store the state of the last ulid created.

Is this something you wanted to implement, or that you have an immediate need for?

camerondavison commented 5 years ago

I don't have any real immediate need. I may try and put together a pull request for it. Unsure if I will have time. Do you have any other architecture suggestions besides having a generator that keeps track of the last ulid?

dylanhart commented 5 years ago

The generator will likely use an algorithm similar to:

  1. Create a new DateTime using the chrono library
  2. Compare that with the last ulid's datetime to see if it's in the same millisecond (see Ulid::datetime())
  3. If it's within the same millisecond call Ulid::increment() to get a monotonic ulid. (needs implementation, signature: fn increment(&self) -> Option<Ulid>)
    • If an overflow occurs, None will be returned
  4. Otherwise use Ulid::from_datetime() to create a new Ulid

struct Generator {
    previous: Option<Ulid>;
}

impl Generator {
    fn new() -> Generator { ... }
    fn generate(&mut self) -> Result<Ulid, MontonicError> { ... }
}

enum MonotonicError {
    Overflow,
}
dylanhart commented 5 years ago

I'll assign this to you for the next week. If you don't get around to it, it's no big deal.

camerondavison commented 5 years ago

I found some time this afternoon, and it was easier to knock out than expected. of course if this is not the direction you were expecting then I can change it up.

If you do like it then I can work on putting documentation in the readme as part of the pull request as well.