tagid 0.3.0

Defines a newtype labeled tagging for different types of ids.
Documentation

tagid - Typed Unique Identifiers for Rust Entities

Crates.io Docs.rs License: MIT

tagid provides a robust system for defining and managing typed unique identifiers in Rust.
It supports multiple ID generation strategies (CUID, UUID, Snowflake) and integrates seamlessly with
serde, sqlx, and other frameworks.

Features

  • Typed Identifiers: Define entity-specific IDs with compile-time safety.
  • Multiple ID Generators:
    • CUID (cuid feature) - Compact, collision-resistant IDs.
    • UUID (uuid feature) - Universally unique identifiers.
    • Snowflake (snowflake feature) - Time-based, distributed IDs.
  • Entity Labeling: Labels provide contextual meaning to identifiers.
  • Serialization & Database Support:
    • [serde] integration for JSON and binary serialization (serde feature).
    • [sqlx] integration for database storage (sqlx feature).
  • Custom Labeling: Define custom label formats for entities.

Installation

Add tagid to your Cargo.toml, enabling the desired features:

[dependencies]
tagid = { version = "0.1", features = ["uuid", "sqlx"] }

Optional Features

Feature Description
"derive" Enables #[derive(Label)] macro for automatic labeling.
"cuid" Enables the [CuidGenerator] for CUID-based IDs.
"uuid" Enables the [UuidGenerator] for UUID-based IDs.
"snowflake" Enables the [SnowflakeGenerator] for distributed IDs.
"serde" Enables serialization support via serde.
"sqlx" Enables database integration via sqlx.
"envelope" Provides an envelope struct for wrapping IDs with metadata.

Usage

Defining an Entity with a Typed ID

use tagid::{Entity, Id, Label};

#[derive(Label)]
struct User;

impl Entity for User {
    type IdGen = tagid::UuidGenerator;
}

fn main() {
    let user_id = User::next_id();
    println!("User ID: {}", user_id);
}

Labeling System

Labels help associate an identifier with an entity, improving clarity in logs and databases. The Label trait provides a way to define a unique label for each entity type.

use tagid::{Label, Labeling};

#[derive(Label)]
struct Order;

let order_label = Order::labeler().label();
assert_eq!(order_label, "Order");

This ensures that IDs are self-descriptive when displayed, stored, or logged.

Working with Different ID Types

Using CUIDs

Enable the cuid feature in Cargo.toml:

[dependencies]
tagid = { version = "0.2", features = ["cuid"] }

Example usage:

use tagid::{Entity, Id, Label, CuidGenerator};

#[derive(Label)]
struct Session;

impl Entity for Session {
    type IdGen = CuidGenerator;
}

fn main() {
    let session_id = Session::next_id();
    println!("Session ID: {}", session_id);
}

Using UUIDs

Enable the uuid feature:

[dependencies]
tagid = { version = "0.2", features = ["uuid"] }

Example usage:

use tagid::{Entity, Id, Label, UuidGenerator};

#[derive(Label)]
struct User;

impl Entity for User {
    type IdGen = UuidGenerator;
}

fn main() {
    let user_id = User::next_id();
    println!("User ID: {}", user_id);
}

Using Snowflake IDs

Enable the snowflake feature:

[dependencies]
tagid = { version = "0.2", features = ["snowflake"] }

Example usage:

use tagid::{Entity, Id, Label, snowflake::SnowflakeGenerator};

#[derive(Label)]
struct LogEntry;

impl Entity for LogEntry {
    type IdGen = SnowflakeGenerator;
}

fn main() {
    let log_id = LogEntry::next_id();
    println!("Log ID: {}", log_id);
}

Serialization & Database Integration

JSON Serialization with serde

Enable the serde feature in Cargo.toml

[dependencies]
tagid = { version = "0.2", features = ["serde", "derive"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1"

Then serialize an ID:

use tagid::{Entity, Id, Label};
use serde::{Serialize, Deserialize};

#[derive(Label, Serialize, Deserialize)]
struct Product;

impl Entity for Product {
    type IdGen = tagid::UuidGenerator;
}

fn main() {
    let product_id = Product::next_id();
    let serialized = serde_json::to_string(&product_id).unwrap();
    println!("Serialized ID: {}", serialized);
}

SQL Database Integration with sqlx

Enable sqlx support in Cargo.toml:

[dependencies]
tagid = { version = "0.2", features = ["sqlx", "derive"] }
sqlx = { version = "0.7", features = ["postgres"] }

Then use `Is<T, ID> in a database model:

use tagid::{Entity, Id, Label};
use sqlx::FromRow;

#[derive(Label)]
struct Customer;

impl Entity for Customer {
    type IdGen = tagid::UuidGenerator;
}

#[derive(FromRow)]
struct CustomerRecord {
    id: Id<Customer, uuid::Uuid>,
    name: String,
}

Benchmarking

To measure the performance of difference ID generators, run:

cargo bench

Contributing

Contributions are welcome! Open an issue or submit a pull request on GitHub.

License

This project is licensed under the MIT License. See the LICENSE file for details.