LOG 012

2026/08/21

★ Typed Identifiers

  • Fully documented the syntax and core modules.

  • Cleaned up various marker traits (SubsetOf, SingleCharGraphemes, etc).

  • Cleaned up the trait interface, and finalized the names for all the types.

  • Added an optional Strict profile, which hardens the enforcement of identifier formats.

  • Added more doctests, specifically around SubsetOf, to ensure things are working properly.

The API has been finalized!

I might change around some things (for instance, I’m currently debating if I want to put the syntax module under core), but for the most part it’s complete - just needs more documentation.

It changed a tiny bit from the last time I posted an example, so let’s take another look:

use crate::syntax::{boundary, delimiter, profile};
use crate::{Conversion, Ident, Chunk};

// A lower_snake_case identifier using the Unicode XID profile.
type LowerSnakeIdent = Ident<
    boundary::None,
    delimiter::LowLine,
    profile::Lower<profile::Unicode>,
>;

// Only allows lower_snake identifiers.
let ident = LowerSnakeIdent::new("example_snake")?;
assert!(LowerSnakeIdent::new("example-kebab").is_err());
assert!(LowerSnakeIdent::new("exampleCamel").is_err());

// You can easily extract segments of the identifier.
// Prints:
// * Chunk(Chunk("example"))
// * Delimiter(LowLine)
// * Chunk(Chunk("snake"))
println!("{ident} segments:");
for segment in ident.segments() {
    println!("* {segment:?}");
}

// You can also easily convert to other identifiers.
//
// The type here is `IdentBuf<Grapheme, LowLine, UpperCamel<Unicode>>`,
// but you can test against strings (`PartialEq` works against `&str`).
assert_eq!(ident.to_upper_camel()?, "ExampleSnake");