A tagged URN system with flat tag-based naming, pattern matching, and specificity comparison.
Tagged URN provides a formal system for tag-based identifiers with matching and comparison capabilities. It uses a flat key-value tag format that supports special pattern values, graded specificity ranking, and symmetric matching.
- Flat Tag Format - Simple
key=valuepairs separated by semicolons - Special Pattern Values -
*(must-have-any),?(unspecified),!(must-not-have) - Value-less Tags - Tags without values (
tag) are must-have-any (tag=*) - Case Insensitive - All input normalized to lowercase (except quoted values)
- Tag Order Independent - Canonical alphabetical sorting
- Graded Specificity - Exact values score higher than wildcards
- Smart Quoting - Automatic quoting for special characters and case preservation
Tagged URNs use a flat tag-based format: cap:tag1=value1;tag2=value2;tag3=value3
Examples:
cap:op=extract;target=metadata;ext=pdf
cap:image;format=png;quality=high
cap:op=generate;target=thumbnail;output=binary
Special Values:
| Value | Meaning | Example |
|---|---|---|
K=v |
Must have key K with exact value v | format=pdf |
K=* |
Must have key K with any value | format=* |
K=! |
Must NOT have key K | debug=! |
K=? |
No constraint on key K | format=? |
| (missing) | No constraint (same as ?) |
Value-less Tags:
- Tags without values mean must-have-any:
cap:op=extract;optimizeequalscap:op=extract;optimize=* - Useful for asserting tag presence:
cap:premium;feature=export
Specificity:
- Graded scoring: exact value (3) > must-have-any (2) > must-not-have (1) > unspecified (0)
cap:op=extract;ext=pdf(specificity 6) is more specific thancap:op=extract;ext=*(specificity 5)
use tagged_urn::{TaggedUrn, TaggedUrnBuilder};
// Create from string
let urn = TaggedUrn::from_string("cap:op=extract;target=metadata")?;
// Build with builder pattern
let urn = TaggedUrnBuilder::new()
.tag("op", "extract")
.tag("target", "metadata")
.tag("ext", "pdf")
.build()?;
// Check matching - does instance conform to pattern's constraints?
let pattern = TaggedUrn::from_string("cap:op=extract")?;
if urn.conforms_to(&pattern)? {
println!("URN conforms to pattern");
}
// Compare specificity
if urn.is_more_specific_than(&request) {
println!("URN is more specific");
}let instance = TaggedUrn::from_string("cap:op=extract;target=metadata;ext=pdf")?;
let pattern = TaggedUrn::from_string("cap:op=extract")?;
// instance.conforms_to(pattern) - does instance satisfy pattern's constraints?
if instance.conforms_to(&pattern)? {
println!("Instance satisfies pattern");
}
// pattern.accepts(instance) - equivalent, from pattern's perspective
if pattern.accepts(&instance)? {
println!("Pattern accepts instance");
}let general = TaggedUrn::from_string("cap:op=extract")?;
let specific = TaggedUrn::from_string("cap:op=extract;ext=pdf")?;
if specific.is_more_specific_than(&general) {
println!("Specific URN preferred");
}let urn = TaggedUrnBuilder::new()
.tag("inference")
.tag("op", "conversation")
.tag("language", "en")
.build()?;This Rust implementation produces identical results to:
All implementations pass the same test cases and follow identical rules.
cargo testSee RULES.md for the definitive specification of Tagged URN format, syntax, and behavior.
serde- Serialization/deserializationserde_json- JSON supportregex- Pattern validation
MIT License