7 releases (3 stable)
| 1.3.0-alpha |
|
|---|---|
| 1.2.1 | Jan 18, 2026 |
| 1.2.0-alpha |
|
| 1.0.5 | May 6, 2025 |
#230 in Data structures
4,082 downloads per month
Used in 21 crates
(via mti)
37KB
422 lines
TypeID Prefix
A Rust library that implements robust validation and sanitization for the prefix component of TypeIDs, strictly adhering to the rules defined in the official TypeID Specification.
TypeIDs are globally unique, type-prefixed identifiers. This crate focuses only on the prefix part, ensuring it conforms to the specification's requirements for length, character set, and structure.
It can be combined with crates handling the suffix part (like the TypeIdSuffix crate) to build complete TypeID solutions, such as the mti (Magic Type Id) crate. For a holistic implementation of the TypeID specification, consider using the mti crate.
Conformance to TypeID Specification
This crate ensures that TypeIdPrefix instances adhere to the following rules for prefixes as outlined in the TypeID Specification:
- Maximum Length: Prefixes must be no more than 63 characters long.
- Character Set: Prefixes must consist of lowercase ASCII letters (
a-z). This crate also permits underscores (_) as internal separators, but ensures they do not violate start/end rules. - Structure:
- Must start with a lowercase ASCII letter.
- Must end with a lowercase ASCII letter.
- Therefore, prefixes cannot start or end with an underscore.
- Non-Empty: An empty string is not a valid prefix.
The validation and sanitization logic within this crate is designed to enforce these rules rigorously.
Features
- Type-safe: Ensures that
TypeIDprefixes conform to the specification. - Validation: Provides robust validation for
TypeIDprefixes against specification rules. - Sanitization: Offers methods to clean and sanitize input strings into valid
TypeIDprefixes. - Zero-cost abstractions: Designed to have minimal runtime overhead.
- Optional tracing: Integrates with the
tracingcrate for logging (optional feature).
Installation
Add this to your Cargo.toml:
[dependencies]
typeid_prefix = "1.0.0" # Replace with the latest version
To enable tracing support, add:
[dependencies]
typeid_prefix = { version = "1.0.0", features = ["instrument"] } # Replace with the latest version
Usage
Basic Usage
use typeid_prefix::{TypeIdPrefix, PrefixFactory}; // Assuming Sanitize is re-exported or use PrefixFactory
use std::convert::TryFrom;
// If using PrefixFactory directly:
// use typeid_prefix::PrefixFactory;
fn main() {
// Create a TypeIdPrefix from a valid string
let prefix = TypeIdPrefix::try_from("user").unwrap();
println!("Valid prefix: {}", prefix);
// Attempt to create from an invalid string (e.g., contains uppercase)
let result_invalid_char = TypeIdPrefix::try_from("Invalid_Prefix");
assert!(result_invalid_char.is_err());
if let Err(e) = result_invalid_char {
println!("Error for 'Invalid_Prefix': {}", e);
}
// Attempt to create from an empty string (invalid)
let result_empty = TypeIdPrefix::try_from("");
assert!(result_empty.is_err());
if let Err(e) = result_empty {
println!("Error for empty string: {}", e);
}
// Sanitize an invalid string
// Note: The original example used `sanitize_and_create()`.
// Assuming this comes from a trait like `Sanitize` or `PrefixFactory`.
// If `PrefixFactory` is used:
let sanitized = "Invalid_Prefix123".create_prefix_sanitized();
// let sanitized = "Invalid_Prefix123".sanitize_and_create(); // Using the provided example's trait
println!("Sanitized prefix: {}", sanitized); // Expected: "invalid_prefix"
}
Validation
The TypeIdPrefix type ensures that all instances conform to the TypeID specification rules mentioned in the "Conformance" section.
use typeid_prefix::TypeIdPrefix;
use std::convert::TryFrom;
fn validate_prefix(input: &str) {
match TypeIdPrefix::try_from(input) {
Ok(prefix) => println!("'{}' is a valid prefix: {}", input, prefix),
Err(e) => println!("'{}' is an invalid prefix: {}", input, e),
}
}
fn main() {
validate_prefix("valid_prefix"); // Valid
validate_prefix("Invalid_Prefix"); // Invalid: ContainsInvalidCharacters
validate_prefix("_invalid"); // Invalid: StartsWithUnderscore or InvalidStartCharacter
validate_prefix("invalid_"); // Invalid: EndsWithUnderscore or InvalidEndCharacter
validate_prefix(""); // Invalid: IsEmpty or InvalidStartCharacter
validate_prefix("toolong_toolong_toolong_toolong_toolong_toolong_toolong_toolong"); // Invalid: ExceedsMaxLength
}
Sanitization
The PrefixFactory trait (implemented for string types) provides create_prefix_sanitized() to clean and attempt to create a valid TypeIdPrefix.
use typeid_prefix::PrefixFactory;
fn main() {
// Using PrefixFactory
let sanitized = "Invalid String 123!@#".create_prefix_sanitized();
println!("Sanitized: {}", sanitized); // Outputs: invalidstring
let sanitized_with_underscores = "_Another Example_".create_prefix_sanitized();
println!("Sanitized: {}", sanitized_with_underscores); // Outputs: another_example
let sanitized_empty_result = "!@#$%^".create_prefix_sanitized();
println!("Sanitized (empty result): {}", sanitized_empty_result); // Outputs an empty TypeIdPrefix (default)
}
Optional Tracing
When the instrument feature is enabled, the crate will log validation errors using the tracing crate:
[dependencies]
typeid_prefix = { version = "1.0.0", features = ["instrument"] } # Replace with the latest version
use typeid_prefix::PrefixFactory;
fn main() {
// Set up your tracing subscriber here (e.g., tracing_subscriber::fmt::init();)
// This will log if sanitization leads to an invalid state or if try_create_prefix fails.
let _attempt = "Invalid_Prefix!@#".try_create_prefix();
let _sanitized = "Invalid_Prefix!@#".create_prefix_sanitized();
// Validation errors encountered internally might be logged via tracing
}
Use Cases
- Database Systems: Use
TypeIdPrefixto ensure consistent and valid type prefixes for database schemas or ORM mappings, aligning with TypeID standards. - API Development: Validate and sanitize user input for API endpoints that require TypeID prefixes, ensuring adherence to the specification.
- Code Generation: Generate valid TypeID prefixes for code generation tools or macros.
- Configuration Management: Ensure configuration keys or identifiers that act as TypeID prefixes conform to a consistent format.
Safety and Correctness
This crate has been thoroughly tested and verified:
- Comprehensive unit tests
- Property-based testing with
proptest - Fuzz testing
- Formal verification with Kani (if applicable, confirm this is still accurate)
These measures ensure that the crate behaves correctly according to the TypeID prefix specification and aims to prevent panics under normal usage.
Minimum Supported Rust Version (MSRV)
This crate is guaranteed to compile on Rust 1.60.0 and later.
License
This project is licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Credits
This crate implements the prefix validation and sanitization rules from the TypeID Specification created by Jetpack.io.## Sponsor
Govcraft is a one-person shop—no corporate backing, no investors, just me building useful tools. If this project helps you, sponsoring keeps the work going.
Dependencies
~0–1.9MB
~15K SLoC