Crate mti

Source
Expand description

§Magic Type ID (MTI): Empowering Distributed Systems with Intelligent Identifiers

Welcome to mti, a Rust crate that brings the power of type-safe, prefix-enhanced identifiers to your distributed systems. Built on the TypeID Specification, mti combines the uniqueness of UUIDs with the readability and type safety of prefixed identifiers, offering a robust solution for managing identifiers across your applications.

§Why Magic Type ID?

In the world of distributed systems and microservices, having unique, type-safe, and human-readable identifiers is crucial. Magic Type ID solves this challenge by providing:

  • Type Safety: Embed type information directly in your identifiers.
  • Readability: Human-readable prefixes make identifiers self-descriptive.
  • Uniqueness: Utilizes UUIDs (including UUIDv7) for guaranteed global uniqueness.
  • Sortability: When using UUIDv7, identifiers are inherently time-sortable.
  • Flexibility: Support for various UUID versions and custom prefixes.
  • Ease of Use: Intuitive API with “magical” creation methods.

§Quick Start

Add mti to your Cargo.toml:

[dependencies]
mti = "1.0"

Then, in your Rust code:

use std::str::FromStr;
use mti::prelude::*;

// Create a MagicTypeId for a user
let user_id = "user".create_type_id::<V7>();
println!("New User ID: {}", user_id); // e.g., "user_01h455vb4pex5vsknk084sn02q"

// Parse an existing MagicTypeId
let order_id = MagicTypeId::from_str("order_01h455vb4pex5vsknk084sn02q").unwrap();
assert_eq!(order_id.prefix().as_str(), "order");

§Key Features

§1. Effortless Creation with Type Safety

Create identifiers with type information embedded:

use mti::prelude::*;

let product_id = "product".create_type_id::<V4>();
let user_id = "user".create_type_id::<V7>();

§2. Flexible Prefix Handling

Magic Type ID offers both infallible and fallible prefix creation:

use mti::prelude::*;

// Infallible - always produces a valid prefix
let sanitized_id = "Invalid Prefix!".create_type_id::<V7>();
assert!(sanitized_id.to_string().starts_with("invalidprefix_"));

// Fallible - returns an error for invalid prefixes
let result = "Invalid Prefix!".try_create_type_id::<V7>();
assert!(result.is_err());

§3. UUID Version Flexibility

Support for UUID versions 1 through 7, defaulting to the time-sortable UUIDv7:

use mti::prelude::*;

let v4_id = "data".create_type_id::<V4>();
let v7_id = "data".create_type_id::<V7>();

§4. Seamless String-Like Behavior

MagicTypeIds can be used in most contexts where you’d use a string:

use mti::prelude::*;

let id = "user".create_type_id::<V7>();
assert!(id.starts_with("user_"));
assert_eq!(id.len(), 31);

§5. Robust Error Handling

Comprehensive error types for invalid prefixes or UUIDs:

use std::str::FromStr;
use mti::prelude::*;

let result = MagicTypeId::from_str("invalid!_01h455vb4pex5vsknk084sn02q");
match result {
    Ok(_) => println!("Valid MagicTypeId"),
    Err(e) => println!("Error: {}", e),
}

§Advanced Usage

§Custom Type-Safe ID Types

Create custom ID types for enhanced type safety:

use mti::prelude::*;

struct UserId(MagicTypeId);
struct OrderId(MagicTypeId);

impl UserId {
    fn new() -> Self {
        Self("user".create_type_id::<V7>())
    }
}

impl OrderId {
    fn new() -> Self {
        Self("order".create_type_id::<V7>())
    }
}

let user_id = UserId::new();
let order_id = OrderId::new();

// Compile-time type safety
fn process_user(id: UserId) { /* ... */ }
fn process_order(id: OrderId) { /* ... */ }

process_user(user_id);
process_order(order_id);
// process_user(order_id); // This would cause a compile-time error!

§Seamless Database Integration

MagicTypeIds can be easily integrated with database libraries:

use mti::prelude::*;
use some_db_library::Database;

#[derive(Debug)]
struct User {
    id: MagicTypeId,
    name: String,
}

fn create_user(db: &Database, name: &str) -> User {
    let user = User {
        id: "user".magic_type_id::<V7>(),
        name: name.to_string(),
    };
    db.insert("users", &user);
    user
}

fn get_user(db: &Database, id: &MagicTypeId) -> Option<User> {
    db.get("users", id)
}

§Performance and Safety

Magic Type ID is designed with performance and safety in mind:

  • Zero-cost abstractions for string-like operations.
  • Built on top of the thoroughly tested and verified TypeIdPrefix and TypeIdSuffix crates.
  • Efficient UUID generation and manipulation.

§Learn More

  • Explore the [MagicTypeId] struct for core functionality.
  • Check out the [MagicTypeIdExt] trait for powerful string extension methods.
  • See the errors module for comprehensive error handling.

§Contributing

We welcome contributions! Please see my GitHub repository for issues, feature requests, and pull requests.

§License

This project is licensed under either of

at your option.

Happy coding with Magic Type ID! 🎩✨

Modules§

prelude
A prelude module that re-exports the most commonly used types and traits.