| Crates.io | domain-key |
| lib.rs | domain-key |
| version | 0.1.1 |
| created_at | 2025-07-10 06:19:55.479277+00 |
| updated_at | 2025-07-10 17:36:35.496507+00 |
| description | High-performance, domain-driven, type-safe key system for Rust |
| homepage | https://github.com/vanyastaff/domain-key |
| repository | https://github.com/vanyastaff/domain-key |
| max_upload_size | |
| id | 1745942 |
| size | 332,643 |
High-performance, type-safe, domain-driven key system for Rust applications
Never mix up keys from different domains again! ๐ฏ
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(())
}
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>(())
# 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"]
# 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"
| 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 |
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>(())
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>(())
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>(())
fast - GxHash (40% faster, requires modern CPU with AES-NI)secure - AHash (DoS protection, balanced performance)crypto - Blake3 (cryptographically secure)std - Standard library support (enabled by default)serde - Serialization support (enabled by default)no_std - No standard library supportdomain-key provides multiple levels of security depending on your needs:
secure feature for AHash with DoS resistancecrypto feature for Blake3 cryptographic hashingSee SECURITY.md for detailed security information.
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
# 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
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);
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>(())
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
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 | 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 |
This project is licensed under the MIT License - see the LICENSE file for details.
smartstring crate for memory efficiencydomain-key - Because your keys should know their place in your domain! ๐๏ธ