I've created a simple algorithm, implemented it in Rust, and published it as a crate on crates.io.
https://crates.io/crates/randevu
My code seems pretty clean and idiomatic to me, but I'd like to know if you have suggestions to improve it further, including tests and documentation.
I want to allow users to pass a chrono date/time to the function instead of the function only taking the date as a string.
I'm also considering making a version that accepts blake3 hashes of object and date (so they can be calculated only once for instances where the function is called many times for a specific object or date).
For those interested in the function and idea behind the algorithm itself, I've tried to explain it the best I can in the README.md (though it might not be relevant for code review).
//! The official Rust implementation of the [RANDEVU](https://github.com/TypicalHog/randevu) algorithm
//!
//! # Example
//! ```rust
//! use randevu::{rdv, utc_date_with_offset};
//!
//! fn main() {
//! let object = "THE_SIMPSONS";
//! let date = utc_date_with_offset(0);
//! let rdv = rdv(object, &date);
//!
//! println!("Object {} has RDV{} today", object, rdv);
//! }
//! ```
use blake3;
use chrono::{TimeDelta, Utc};
/// Returns current UTC DATE `String` in ISO 8601 format (YYYY-MM-DD), with an OFFSET `i64` in days
pub fn utc_date_with_offset(offset: i64) -> String {
(Utc::now() + TimeDelta::days(offset))
.format("%Y-%m-%d")
.to_string()
}
/// Returns RDV level `u32` for an OBJECT `&str` on a specific DATE `&str`
///
/// **RDV = number of leading zero bits in blake3(blake3(OBJECT) || blake3(DATE))**
pub fn rdv(object: &str, date: &str) -> u32 {
let mut hasher = blake3::Hasher::new();
hasher.update(blake3::hash(object.as_bytes()).as_bytes());
hasher.update(blake3::hash(date.as_bytes()).as_bytes());
let final_hash = hasher.finalize();
let mut rdv = 0;
for &byte in final_hash.as_bytes() {
rdv += byte.leading_zeros();
if byte != 0 {
break;
}
}
rdv
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rdv_1() {
assert_eq!(rdv("NO_BOILERPLATE", "2024-01-26"), 11);
}
#[test]
fn test_rdv_2() {
assert_eq!(rdv("SHREK_2001", "2024-01-26"), 8);
}
#[test]
fn test_rdv_3() {
assert_eq!(rdv("RANDEVU", "2024-01-26"), 1);
}
#[test]
fn test_rdv_4() {
assert_eq!(rdv("RUST", "2024-01-26"), 0);
}
}