Skip to main content
Common utilities for building distributed systems and applications. This crate provides essential utilities with full WebAssembly support and optional database integration.

Features

  • Unique Identifiers: ULID-based sortable and unique ID generation supporting both random and worker-based approaches
  • UTC DateTime Handling: A UTC-focused datetime type optimized for distributed systems
  • WASM Compatible: Full support for WebAssembly targets
  • Database Support: PostgreSQL and MySQL integration via optional features

Installation

Add bomboni_common to your Cargo.toml:
[dependencies]
bomboni_common = "*"

Optional Features

Enable serialization and deserialization with serde
Enable async APIs using tokio runtime
Enable conversion with the chrono datetime crate
Enable WebAssembly support
Enable PostgreSQL type conversions
Enable MySQL type conversions

Unique Identifiers

The Id type provides semi-globally unique and sortable identifiers based on ULID (Universally Unique Lexicographically Sortable Identifier).

Random ID Generation

Generate random sortable IDs for general use:
use bomboni_common::id::Id;
use std::str::FromStr;

// Generate a random sortable ID
let id = Id::generate();
println!("ID: {}", id);

// Generate multiple IDs at once (more efficient)
let ids = Id::generate_multiple(5);
assert_eq!(ids.len(), 5);

// IDs are monotonically increasing when generated in sequence
assert!(ids[0] < ids[1]);

Parsing IDs

Parse IDs from string representations:
use bomboni_common::id::Id;

// Parse from ULID string format
let id_str = "01ARZ3NDEKTSV4RRFFQ69G5FAV";
let id: Id = id_str.parse().unwrap();

// Display back to string
assert_eq!(id.to_string(), id_str);

Worker-Based ID Generation

For distributed systems where each worker needs to generate unique IDs without coordination:
use bomboni_common::id::worker::WorkerIdGenerator;

// Create a generator for worker ID 1
let mut g = WorkerIdGenerator::new(1);

// Generate unique IDs for this worker
let id1 = g.generate();
let id2 = g.generate();
assert_ne!(id1, id2);

// Generating multiple IDs at once is more efficient
let ids = g.generate_multiple(3);
assert_eq!(ids.len(), 3);

// Each ID can be decoded back to its components
let (timestamp, worker_id, sequence) = ids[0].decode_worker();
assert_eq!(worker_id, 1);
Each WorkerIdGenerator should have a unique worker ID in your distributed system to ensure global uniqueness. The generator uses a 16-bit worker ID and 16-bit sequence number.

Async ID Generation

With the tokio feature enabled, you can generate IDs in async contexts:
use bomboni_common::id::worker::WorkerIdGenerator;

let mut g = WorkerIdGenerator::new(1);

// Generate single ID asynchronously
let id = g.generate_async().await;

// Generate multiple IDs asynchronously
let ids = g.generate_multiple_async(10).await;

ID Construction and Decoding

Create IDs from components or decode existing IDs:
use bomboni_common::id::Id;
use time::OffsetDateTime;

// Create from worker parts
let timestamp = OffsetDateTime::now_utc();
let id = Id::from_worker_parts(timestamp, 1, 0);

// Decode back to components
let (decoded_time, worker_id, sequence) = id.decode_worker();
assert_eq!(worker_id, 1);
assert_eq!(sequence, 0);

// Create from time and random value
let id = Id::from_time_and_random(timestamp, 12345);
let (decoded_time, random) = id.decode_time_and_random();
assert_eq!(random, 12345);

UTC DateTime

The UtcDateTime type provides a simple, UTC-focused datetime implementation with WASM support.

Basic Usage

use bomboni_common::date_time::UtcDateTime;

// Get the current UTC time
let now = UtcDateTime::now();

// Create from Unix timestamp (seconds)
let dt = UtcDateTime::from_seconds(1609459200).unwrap();
assert_eq!(dt.to_string(), "2021-01-01T00:00:00Z");

// Create from seconds and nanoseconds
let dt = UtcDateTime::new(1609459200, 500000000);
println!("Time: {}", dt);

Parsing and Formatting

use bomboni_common::date_time::UtcDateTime;

// Parse from RFC 3339 string
let dt = "1970-01-01T00:00:01Z".parse::<UtcDateTime>().unwrap();
assert_eq!(dt.timestamp(), (1, 0));

// Parse explicitly
let dt = UtcDateTime::parse_rfc3339("2021-01-01T12:00:00Z").unwrap();

// Format as RFC 3339 string
let formatted = dt.format_rfc3339().unwrap();
assert_eq!(formatted, "2021-01-01T12:00:00Z");

Timestamp Conversion

use bomboni_common::date_time::UtcDateTime;

// Get timestamp as (seconds, nanoseconds)
let dt = UtcDateTime::now();
let (seconds, nanoseconds) = dt.timestamp();

// Create from nanoseconds
let dt = UtcDateTime::from_nanoseconds(1609459200000000000).unwrap();
assert_eq!(dt.to_string(), "2021-01-01T00:00:00Z");

Chrono Integration

With the chrono feature enabled:
use bomboni_common::date_time::UtcDateTime;
use chrono::{DateTime, Utc, NaiveDateTime};

// Convert from chrono DateTime
let chrono_dt = DateTime::parse_from_rfc3339("2020-01-01T12:00:00Z")
    .unwrap()
    .to_utc();
let utc_dt = UtcDateTime::try_from(chrono_dt).unwrap();

// Convert to chrono DateTime
let chrono_dt: DateTime<Utc> = utc_dt.into();

// Convert from/to NaiveDateTime
let naive = NaiveDateTime::parse_from_str("2020-01-01 12:00:00", "%Y-%m-%d %H:%M:%S")
    .unwrap();
let utc_dt = UtcDateTime::try_from(naive).unwrap();
let naive_back: NaiveDateTime = utc_dt.into();

Database Integration

PostgreSQL

With the postgres feature, Id and UtcDateTime types can be used directly with PostgreSQL queries.

MySQL

With the mysql feature, Id and UtcDateTime types can be used directly with MySQL queries.

Serialization

With the serde feature enabled:
use bomboni_common::id::Id;
use bomboni_common::date_time::UtcDateTime;

// Serialize/deserialize IDs as strings
let id = Id::generate();
let json = serde_json::to_string(&id).unwrap();
let parsed: Id = serde_json::from_str(&json).unwrap();
assert_eq!(id, parsed);

// Serialize/deserialize datetime as RFC 3339 strings
let dt = UtcDateTime::now();
let json = serde_json::to_string(&dt).unwrap();
let parsed: UtcDateTime = serde_json::from_str(&json).unwrap();
assert_eq!(dt, parsed);

API Reference

Id Type

Id
struct
A semi-globally unique and sortable identifier based on ULID.Methods:
  • generate() - Generates a new random sortable ID
  • generate_multiple(count) - Generates multiple random IDs efficiently
  • from_worker_parts(time, worker, sequence) - Creates ID from worker components
  • from_time_and_random(time, random) - Creates ID from time and random value
  • decode_worker() - Decodes ID into (timestamp, worker, sequence)
  • decode_time_and_random() - Decodes ID into (timestamp, random)

WorkerIdGenerator Type

WorkerIdGenerator
struct
Generator for IDs with a specific worker identifier for distributed systems.Methods:
  • new(worker) - Creates a new generator with the given worker ID
  • generate() - Generates a new ID (blocking)
  • generate_async() - Generates a new ID (async, requires tokio feature)
  • generate_multiple(count) - Generates multiple IDs efficiently (blocking)
  • generate_multiple_async(count) - Generates multiple IDs efficiently (async)

UtcDateTime Type

UtcDateTime
struct
A date and time in the UTC timezone.Methods:
  • now() - Returns the current UTC time
  • new(seconds, nanoseconds) - Creates from seconds and nanoseconds
  • from_timestamp(seconds, nanoseconds) - Creates with error handling
  • from_seconds(seconds) - Creates from Unix timestamp
  • from_nanoseconds(nanos) - Creates from nanoseconds
  • timestamp() - Returns (seconds, nanoseconds) tuple
  • parse_rfc3339(string) - Parses RFC 3339 formatted string
  • format_rfc3339() - Formats as RFC 3339 string

bomboni_core

Core utilities and abstractions

bomboni_macros

Convenient utility macros

Build docs developers (and LLMs) love