namecode
Punycode for variable names
Reversible encoding from arbitrary Unicode to valid identifiers. O(n). No dependencies beyond unicode-ident.
| Input | encode() | |
|---|---|---|
foo | foo | Already valid — identity |
café | café | Valid Unicode identifier — identity |
hello world | _N_helloworld__fa0b | Space is not XID_Continue |
foo-bar | _N_foobar__da1d | Hyphen is not XID_Continue |
123foo | _N_123foo | Digit is not XID_Start |
_N_test | _N__N_test | Prefix collision |
Identity
Valid identifiers pass through unchanged. encode(s) == s when s is already UAX 31.
Roundtrip
decode(encode(s)) == s for all strings. encode(decode(s)) == s for all valid encodings.
Idempotent
encode(encode(s)) == encode(s). Encoding an already-encoded string is a no-op.
Cross-language
Output conforms to UAX 31. Valid in Rust, Go, Python, and JavaScript.
cargo add namecode
use namecode::{encode, decode};
let encoded = encode("hello world");
assert_eq!(encoded, "_N_helloworld__fa0b");
assert_eq!(decode(&encoded).unwrap(), "hello world");