commit b261738f55f9c7bcc90ec84c308a8d28eea3d568
parent ec575484da02cf9aa3f9c07eacf6e3b2102d64bb
Author: triesap <triesap@radroots.dev>
Date: Mon, 19 Jan 2026 07:10:35 +0000
app-utils: add id helpers
- add uuidv4 and uuidv7 helpers
- add base64url encoding variants
- add d_tag_create alias helper
- add unit tests for id formats
Diffstat:
5 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -1575,12 +1575,14 @@ dependencies = [
name = "radroots-app-utils"
version = "0.1.0"
dependencies = [
+ "base64",
"futures",
"getrandom 0.2.17",
"gloo-timers",
"js-sys",
"radroots-types",
"serde_json",
+ "uuid",
"web-sys",
]
diff --git a/Cargo.toml b/Cargo.toml
@@ -70,6 +70,7 @@ url = "2"
chrono = "0.4"
hex = "0.4"
sha2 = "0.10"
+uuid = { version = "1.8", features = ["v4", "v7"] }
radroots-nostr = { path = "refs/crates/nostr" }
radroots-types = { path = "refs/crates/types" }
radroots-sql-core = { path = "refs/crates/sql-core" }
diff --git a/crates/utils/Cargo.toml b/crates/utils/Cargo.toml
@@ -15,6 +15,8 @@ getrandom = { workspace = true }
js-sys = { workspace = true }
web-sys = { workspace = true }
serde_json = { workspace = true }
+uuid = { workspace = true }
+base64 = { workspace = true }
[target.'cfg(target_arch = "wasm32")'.dependencies]
gloo-timers = { workspace = true }
diff --git a/crates/utils/src/id/mod.rs b/crates/utils/src/id/mod.rs
@@ -0,0 +1,55 @@
+#![forbid(unsafe_code)]
+
+use base64::engine::general_purpose::URL_SAFE_NO_PAD;
+use base64::Engine;
+use uuid::Uuid;
+
+pub fn uuidv4() -> String {
+ Uuid::new_v4().to_string()
+}
+
+pub fn uuidv7() -> String {
+ Uuid::now_v7().to_string()
+}
+
+pub fn uuidv4_b64url() -> String {
+ URL_SAFE_NO_PAD.encode(Uuid::new_v4().as_bytes())
+}
+
+pub fn uuidv7_b64url() -> String {
+ URL_SAFE_NO_PAD.encode(Uuid::now_v7().as_bytes())
+}
+
+pub fn d_tag_create() -> String {
+ uuidv7_b64url()
+}
+
+#[cfg(test)]
+mod tests {
+ use super::{d_tag_create, uuidv4, uuidv4_b64url, uuidv7, uuidv7_b64url};
+
+ #[test]
+ fn uuidv4_has_expected_length() {
+ assert_eq!(uuidv4().len(), 36);
+ }
+
+ #[test]
+ fn uuidv7_has_expected_length() {
+ assert_eq!(uuidv7().len(), 36);
+ }
+
+ #[test]
+ fn uuidv4_b64url_has_expected_length() {
+ assert_eq!(uuidv4_b64url().len(), 22);
+ }
+
+ #[test]
+ fn uuidv7_b64url_has_expected_length() {
+ assert_eq!(uuidv7_b64url().len(), 22);
+ }
+
+ #[test]
+ fn d_tag_create_uses_uuidv7_b64url() {
+ assert_eq!(d_tag_create().len(), 22);
+ }
+}
diff --git a/crates/utils/src/lib.rs b/crates/utils/src/lib.rs
@@ -4,6 +4,7 @@ pub mod error;
pub mod errors;
pub mod r#async;
pub mod binary;
+pub mod id;
pub mod numbers;
pub mod object;
pub mod path;
@@ -13,6 +14,7 @@ pub mod types;
pub use r#async::exe_iter;
pub use binary::{as_array_buffer, RadrootsAppArrayBuffer};
+pub use id::{d_tag_create, uuidv4, uuidv4_b64url, uuidv7, uuidv7_b64url};
pub use errors::{err_msg, handle_err, throw_err, ERR_PREFIX_APP, ERR_PREFIX_UTILS};
pub use numbers::{num_interval_range, num_str, parse_float, parse_int};
pub use object::{obj_en, obj_result, obj_results_str, obj_truthy_fields};