#type-safe #ddd #domain #key #performance

no-std domain-key

High-performance, domain-driven, type-safe key system for Rust

2 releases

0.1.1 Jul 10, 2025
0.1.0 Jul 10, 2025

#340 in Data structures

MIT license

230KB
3.5K SLoC

domain-key ๐Ÿš€

High-performance, type-safe, domain-driven key system for Rust applications

Crates.io Documentation License Build Status Rust Version

Never mix up keys from different domains again! ๐ŸŽฏ

โœจ What is domain-key?

domain-key brings Domain-Driven Design principles to key management in Rust. It provides compile-time guarantees that keys from different business domains cannot be accidentally mixed or compared, while delivering exceptional performance through advanced optimizations.

use domain_key::{Key, KeyDomain};

// Define your business domains
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
struct UserDomain;

#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
struct OrderDomain;

impl KeyDomain for UserDomain {
    const DOMAIN_NAME: &'static str = "user";
}

impl KeyDomain for OrderDomain {
    const DOMAIN_NAME: &'static str = "order";
}

// Create domain-specific key types
type UserKey = Key<UserDomain>;
type OrderKey = Key<OrderDomain>;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Use them safely
    let user_id = UserKey::new("user_123")?;
    let order_id = OrderKey::new("order_456")?;

    // This won't compile! ๐Ÿ›ก๏ธ
    // let mixed = user_id == order_id; // Compile error!
    
    println!("User: {}", user_id.as_str());
    println!("Order: {}", order_id.as_str());
    Ok(())
}

๐ŸŽฏ Key Features

  • ๐Ÿ”’ Type Safety: Different key types cannot be mixed at compile time
  • ๐ŸŽ๏ธ High Performance: Up to 75% performance improvements through advanced optimizations
  • ๐ŸŽฏ Domain Agnostic: No built-in assumptions about specific domains
  • ๐Ÿ’พ Memory Efficient: Smart string handling with stack allocation for short keys
  • ๐Ÿ›ก๏ธ DoS Resistant: Optional protection against HashDoS attacks
  • ๐Ÿ”ง Extensible: Easy to add new domains and validation rules
  • ๐Ÿ“ฆ Zero-Cost Abstractions: No runtime overhead for type separation
  • ๐ŸŒ Cross-Platform: Works on all major platforms including WebAssembly

๐Ÿš€ Quick Start

Add to your Cargo.toml:

[dependencies]
domain-key = "0.1"

# For maximum performance
domain-key = { version = "0.1", features = ["fast"] }

# For security-critical applications  
domain-key = { version = "0.1", features = ["secure"] }

Define a domain and create keys:

use domain_key::{Key, KeyDomain};

// 1. Define your domain
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
struct UserDomain;

impl KeyDomain for UserDomain {
    const DOMAIN_NAME: &'static str = "user";
    const MAX_LENGTH: usize = 32;
    const TYPICALLY_SHORT: bool = true; // Optimization hint
}

// 2. Create a type alias
type UserKey = Key<UserDomain>;

// 3. Use it!
let user_key = UserKey::new("john_doe")?;
let composed_key = UserKey::from_parts(&["user", "123", "profile"], "_")?;

println!("Domain: {}", user_key.domain());
println!("Length: {}", user_key.len()); // O(1) with optimizations
println!("Key: {}", user_key.as_str());
# Ok::<(), domain_key::KeyParseError>(())

๐ŸŽ๏ธ Performance Features

Feature-Based Optimization Profiles

# Maximum performance (modern CPUs with AES-NI)
features = ["fast"]

# DoS protection + good performance
features = ["secure"]

# Cryptographic security
features = ["crypto"]

# All optimizations enabled
features = ["fast", "std", "serde"]

Build for Maximum Performance

# Enable CPU-specific optimizations
RUSTFLAGS="-C target-cpu=native" cargo build --release --features="fast"

# For Apple Silicon Macs
RUSTFLAGS="-C target-cpu=native -C target-feature=+aes,+neon" cargo build --release --features="fast"

Performance Improvements

Operation Standard Optimized Improvement
Key Creation (short) 100ns 72ns 28% faster
String Operations 100% baseline 175% 75% faster
Hash Operations 25ns 15ns 40% faster
Length Access O(n) O(1) Constant time
Collection Lookup 35ns 21ns 40% faster

๐Ÿ“– Advanced Examples

E-commerce Domain

use domain_key::{Key, KeyDomain};

#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
struct ProductDomain;

#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
struct CartDomain;

impl KeyDomain for ProductDomain {
    const DOMAIN_NAME: &'static str = "product";
    const MAX_LENGTH: usize = 32;
}

impl KeyDomain for CartDomain {
    const DOMAIN_NAME: &'static str = "cart";
    const MAX_LENGTH: usize = 64;
}

type ProductKey = Key<ProductDomain>;
type CartKey = Key<CartDomain>;

// Use in your application
let product = ProductKey::new("laptop_dell_xps13")?;
let cart = CartKey::from_parts(&["cart", "user123", "session456"], "_")?;
# Ok::<(), domain_key::KeyParseError>(())

Multi-tenant SaaS

use domain_key::{Key, KeyDomain, KeyParseError};
use std::borrow::Cow;

#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
struct TenantDomain;

impl KeyDomain for TenantDomain {
    const DOMAIN_NAME: &'static str = "tenant";
    const HAS_CUSTOM_VALIDATION: bool = true;
    const HAS_CUSTOM_NORMALIZATION: bool = true;
    
    fn validate_domain_rules(key: &str) -> Result<(), KeyParseError> {
        if !key.starts_with("tenant_") {
            return Err(KeyParseError::domain_error(
                Self::DOMAIN_NAME,
                "Tenant keys must start with 'tenant_'"
            ));
        }
        Ok(())
    }
    
    fn normalize_domain(key: Cow<'_, str>) -> Cow<'_, str> {
        // Convert to lowercase for consistency
        if key.chars().any(|c| c.is_ascii_uppercase()) {
            Cow::Owned(key.to_ascii_lowercase())
        } else {
            key
        }
    }
}

type TenantKey = Key<TenantDomain>;

let tenant = TenantKey::new("TENANT_acme_corp")?;
assert_eq!(tenant.as_str(), "tenant_acme_corp"); // normalized
# Ok::<(), domain_key::KeyParseError>(())

Advanced Validation

use domain_key::{Key, KeyDomain, KeyParseError};

#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
struct EmailDomain;

impl KeyDomain for EmailDomain {
    const DOMAIN_NAME: &'static str = "email";
    const MAX_LENGTH: usize = 254;
    const HAS_CUSTOM_VALIDATION: bool = true;

    fn validate_domain_rules(key: &str) -> Result<(), KeyParseError> {
        if !key.contains('@') {
            return Err(KeyParseError::domain_error(
                Self::DOMAIN_NAME,
                "Email must contain @ symbol"
            ));
        }

        let parts: Vec<&str> = key.split('@').collect();
        if parts.len() != 2 || parts[0].is_empty() || parts[1].is_empty() {
            return Err(KeyParseError::domain_error(
                Self::DOMAIN_NAME,
                "Invalid email format"
            ));
        }

        Ok(())
    }

    fn allowed_characters(c: char) -> bool {
        c.is_ascii_alphanumeric() || "@._+-".contains(c)
    }
}

type EmailKey = Key<EmailDomain>;

let email = EmailKey::new("user@example.com")?;
assert_eq!(email.as_str(), "user@example.com");

// This will fail validation
let invalid = EmailKey::new("not-an-email");
assert!(invalid.is_err());
# Ok::<(), domain_key::KeyParseError>(())

๐Ÿ”ง Feature Flags Reference

Hash Algorithm Features (choose one for best results)

  • fast - GxHash (40% faster, requires modern CPU with AES-NI)
  • secure - AHash (DoS protection, balanced performance)
  • crypto - Blake3 (cryptographically secure)
  • Default - Standard hasher (good compatibility)

Core Features

  • std - Standard library support (enabled by default)
  • serde - Serialization support (enabled by default)
  • no_std - No standard library support

๐Ÿ›ก๏ธ Security Considerations

domain-key provides multiple levels of security depending on your needs:

  • DoS Protection: Use secure feature for AHash with DoS resistance
  • Cryptographic Security: Use crypto feature for Blake3 cryptographic hashing
  • Input Validation: Comprehensive validation pipeline with custom rules
  • Type Safety: Compile-time prevention of key type mixing
  • Memory Safety: Rust's ownership system + additional optimizations

See SECURITY.md for detailed security information.

๐Ÿ“š Documentation

๐Ÿงช Testing

Run the comprehensive test suite:

# All tests with all features
cargo test --all-features

# Property-based tests
cargo test --features std,serde --release -- prop_

# Benchmarks
cargo bench --features fast

# Security audit
cargo audit

๐Ÿ“ˆ Benchmarks

# Run realistic benchmarks
cargo bench --features fast

# Memory usage analysis
cargo test --release memory_usage

# Cross-platform performance
cargo test --features fast --target wasm32-unknown-unknown

๐Ÿ”„ Migration from String Keys

Before (String-based)

let user_id: String = "user_123".to_string();
let order_id: String = "order_456".to_string();

// Dangerous - no compile-time protection!
if user_id == order_id {
    // This could be a bug, but compiler won't catch it
}

let cache_key = format!("cache:{}:{}", user_id, order_id);

After (domain-key)

type UserKey = Key<UserDomain>;
type OrderKey = Key<OrderDomain>;
type CacheKey = Key<CacheDomain>;

let user_id = UserKey::new("user_123")?;
let order_id = OrderKey::new("order_456")?;

// This won't compile - type safety!
// if user_id == order_id { } // Compile error!

let cache_key = CacheKey::from_parts(&[
    "cache", 
    user_id.as_str(), 
    order_id.as_str()
], ":")?;
# Ok::<(), domain_key::KeyParseError>(())

๐Ÿค Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Quick Development Setup

git clone https://github.com/vanyastaff/domain-key.git
cd domain-key

# Install development dependencies
rustup target add wasm32-unknown-unknown
cargo install cargo-audit cargo-hack

# Run tests
cargo test --all-features
cargo clippy --all-features -- -D warnings
cargo fmt

๐ŸŒŸ Platform Support

Platform Status Hash Algorithm Notes
Linux x86_64 โœ… Full GxHash/AHash Best performance with AES-NI
Windows x86_64 โœ… Full GxHash/AHash Full feature support
macOS Intel โœ… Full GxHash/AHash All features supported
macOS Apple Silicon โœ… Full GxHash/AHash Requires explicit AES+NEON flags
WebAssembly โœ… Core DefaultHasher no_std support
ARM64 Linux โœ… Full GxHash/AHash Server deployments
ARM Embedded โœ… Core FNV-1a no_std + no_alloc

๐Ÿ“„ License

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

๐Ÿ™ Acknowledgments

  • Inspired by Domain-Driven Design principles by Eric Evans
  • Built on the excellent smartstring crate for memory efficiency
  • Performance-focused hash algorithms from the Rust ecosystem:
    • ahash for DoS-resistant hashing
    • gxhash for maximum performance
    • blake3 for cryptographic security

๐Ÿ“Š Project Stats

  • Lines of Code: ~3,000 (including comprehensive tests)
  • Test Coverage: >95%
  • Documentation Coverage: >98%
  • Benchmark Coverage: 20+ realistic scenarios
  • no_std Support: โœ…
  • MSRV: Rust 1.75+
  • Platforms: 7+ supported targets

domain-key - Because your keys should know their place in your domain! ๐Ÿ—๏ธ

Dependencies

~0.5โ€“1.7MB
~37K SLoC