Expand description
§typed-ident
A Rust crate for type-safe identifier validation, inspection, and mutation.
§Example
The main benefit of this crate is that it enforces the format of identifiers and checks that they are valid given a profile.
use typed_ident::alloc::convert::*;
use typed_ident::presets::unicode::*;
// Validate the format of input to see that it matches expectations.
let identifier = UpperCamelIdent::new("HTTPServer")?;
// Look at all of the atomic segments of the identifier.
println!("identifier segments:");
for segment in identifier.segments() {
println!("* {segment:?}"); // [Chunk("HTTP"), Chunk("Server")]
}
// Convert to a different format.
let lower_snake = identifier.to_lower_snake_canonical();
println!("as lower-snake: {lower_snake}"); // "http_server"
// Decorate and mutate.
let decorated = identifier.with_circumfix_str("__", "__")?;
println!("with decoration: {decorated}"); // "__HTTPServer__"
// And more! :)§Operations
After constructing a valid Ident, there are many operations that you can perform on it.
cast- Zero-cost conversion from one identifier to another (in cases where the target is a superset representation).join_str- Append a string onto the end of an identifier while preserving chunk boundaries.segments- Break the identifier into its smallest semantically meaningful segments (“identifier words”, and delimiters).trim_decorative_delims- Remove unnecessary delimiters from each end of the identifier.as_<case>_<format>- display formatting identifiers as different formats (e.g.as_lower_camel,as_upper_kebab, etc.)to_<case>_<format>- Conversion to strings for other preset identifier formats (e.g.to_lower_camel,to_upper_kebab, etc.)- string-like operations - Many of the operations you expect on a regular string slice are also here, except they now ensure you cannot produce an invalid identifier (e.g.
split_at,replace,with_suffix, etc.) - typed slicing - Typed information about the identifier travels with
Fragments (sub-slices) of an identifier. - and much more! - See the crate documentation for more information.
§Design
This crate works with base configurable identifier types; Ident and IdentBuf.
The idea is that most common identifier formats can be defined by 3 things:
Boundary- how chunks are broken during segmentation (if at all).Delimiter- the kinds of characters which always delimit chunks of an identifier, regardless of boundary configuration.Profile- the set of valid UTF-8 code points allowed in this format.
We define an “identifier format” as a specific combination of characters, which is constrained to fit an expected pattern. The Delimiter and Profile types define the format, while Boundary defines the segmentation properties.
See the syntax module for more information on configuring identifier syntax.
§Design: Profiles
The crate splits profiles into two categories; character profiles and case profiles.
If no explicit case is expected, you can use the character profiles directly. Otherwise, if you expect some specific case properties, you can wrap the character profile in a case profile (e.g. Lower<Unicode>).
Character Profiles
There are three provided character profiles.
Ascii-ascii_alphabeticstart,ascii_alphanumericchunk start/continue.Unicode-xid_startstart,xid_continuechunk start/continue (with some documented omissions).Strict- Same asUnicode, except chunk start is not allowed to have combining marks (must be an actual, literal character).
Case Profiles
There are four provided casing profiles.
Lower- only accepts non-uppercase/titlecase characters.LowerCamel- The first character in a chunk (or start of an identifier) must be non-uppercase/titlecase.Upper- only accepts non-lowercase/greek-titlecase characters.UpperCamel- The first character in a chunk (or start of an identifier) must be non-lowercase.
§Design: Delimiters
There are five provided delimiters.
AsciiPunctuation- accepts any ASCII punctuation as a delimiter. (no preset uses this, it’s mostly for reference and to have a common ASCII punctuation delimiter)AsciiFlatLine- either the LOW LINE (_) or HYPHEN-MINUS (-) characters.HyphenMinus- the HYPHEN-MINUS (-) character.LowLine- the LOW LINE (_) character.NotDelimited- disallow delimiters of any kind for this identifier. (no preset uses this, it’s provided because this is tricky to implement, and I could see a want for this)
§Presets
The presets defined by this crate are broken into two categories based on whether or not they prefer delimiters.
All provided presets allow for some kind of delimiter, because in all cases delimiters are valuable in cases of ambiguity (consider for instance Tls1.3 - we likely want a break of some kind between the 1 and 3). Though, if you would like, you can produce a version of an identifier completely disallowing delimiters by using the NotDelimited delimiter.
Prefers Delimiters
These are identifiers which prefer there be a delimiter between chunks.
| Delimiter\Casing | Mixed-Case | Lower-Case | Upper-Case |
|---|---|---|---|
Low Line (_) | Mixed_Snake | lower_snake | UPPER_SNAKE |
Hyphen-Minus (-) | Mixed-Kebab | lower-kebab | UPPER-KEBAB |
Prefers Chunk Boundary
These are identifiers which prefer there NOT to be delimiters between chunks, instead depending on casing to separate chunks. (However, delimiters are still allowed, they are only introduced whenever casing would not be able to separate two chunks).
| Delimiter\Casing | Mixed-Case | Lower-Case | Upper-Case |
|---|---|---|---|
Low Line (_) | MixedCamel | lowerCamel | UpperCamel |
Flat Line (- / _) | MixedHybrid | lowerHybrid | UpperHybrid |
§Normalization
This crate does not provide utilities for Unicode normalization.
It seemed like something that would probably be best provided from some other utility crate, and the developer in question could handle using the two features together (e.g. LowerCamelIdent::new_boxed(string.nfc().collect()), or something similar).
If identifiers should treat canonically equivalent spellings as equal, normalize them consistently before validation, storage, and comparison.
§Normalization: NFC
(for storage and general use)
NFC composes canonically equivalent sequences into a standard canonical form. It is commonly useful for storing and comparing text when canonical equivalence should be treated as equality. It does not resolve case differences, compatibility equivalences, or visually confusable characters.
§Normalization: NFKC
(for compatibility normalization)
NFKC converts text to a canonical form while also removing compatibility distinctions, such as mapping full-width 1 to ASCII 1. Because this can discard distinctions that may matter, it should be used only when compatibility equivalence is desired.
For caseless matching, use Unicode’s NFKC_Casefold operation, preferably through a library API that implements it directly.
§Examples
Instead of listing a bunch of examples here on the main README, we have some examples prepared under the examples directory. Specifically, we’ve made a single util with commands that should serve as a good collection of example applications.
You can run any of these with: cargo run --all-features --example api -- {your CLI args here}
You can type --help for details on the commands the util can run.
Modules§
- alloc
- A module for defining typed identifier functionality that relies on allocation.
- core
- Core type definitions that make up this crate.
- presets
- Presets to set commonly used identifier formats.
- syntax
- Syntax definitions for identifiers.
Structs§
- Chunk
- An immutable UTF-8 encoded slice of an
Identwhich contains no delimiters. - Error
- An error when performing some operation on an identifier (or fragment).
- Fragment
- An immutable UTF-8 encoded slice of an
Ident. - Fragment
Buf - A dynamic, growable fragment.
- Ident
- An immutable, UTF-8 encoded, valid identifier string slice.
- Ident
Buf - A dynamic, growable identifier.
Enums§
- Segment
- A part of an identifier returned during segmentation.
Traits§
- Convertible
Identifier - A marker trait that constrains to only identifiers which support preset
conversion (the
To*traits; e.g.ToUpperCamel,ToLowerKebab, etc). - Formattable
Identifier - A marker trait that constrains to only identifiers which support preset
conversion (the
As*traits; e.g.AsUpperCamel,AsLowerKebab, etc). - Identifier
- A trait for dealing with identifiers in a generic way.
Type Aliases§
- StrSegment
- A borrowed, type-erased representation of a
Segment. - String
Segment - An owned, type-erased representation of a
Segment.