wasm_bindgen_shared/
identifier.rs

1/// Returns whether a character has the Unicode `ID_Start` properly.
2///
3/// This is only ever-so-slightly different from `XID_Start` in a few edge
4/// cases, so we handle those edge cases manually and delegate everything else
5/// to `unicode-ident`.
6fn is_id_start(c: char) -> bool {
7    match c {
8        '\u{037A}' | '\u{0E33}' | '\u{0EB3}' | '\u{309B}' | '\u{309C}' | '\u{FC5E}'
9        | '\u{FC5F}' | '\u{FC60}' | '\u{FC61}' | '\u{FC62}' | '\u{FC63}' | '\u{FDFA}'
10        | '\u{FDFB}' | '\u{FE70}' | '\u{FE72}' | '\u{FE74}' | '\u{FE76}' | '\u{FE78}'
11        | '\u{FE7A}' | '\u{FE7C}' | '\u{FE7E}' | '\u{FF9E}' | '\u{FF9F}' => true,
12        _ => unicode_ident::is_xid_start(c),
13    }
14}
15
16/// Returns whether a character has the Unicode `ID_Continue` properly.
17///
18/// This is only ever-so-slightly different from `XID_Continue` in a few edge
19/// cases, so we handle those edge cases manually and delegate everything else
20/// to `unicode-ident`.
21fn is_id_continue(c: char) -> bool {
22    match c {
23        '\u{037A}' | '\u{309B}' | '\u{309C}' | '\u{FC5E}' | '\u{FC5F}' | '\u{FC60}'
24        | '\u{FC61}' | '\u{FC62}' | '\u{FC63}' | '\u{FDFA}' | '\u{FDFB}' | '\u{FE70}'
25        | '\u{FE72}' | '\u{FE74}' | '\u{FE76}' | '\u{FE78}' | '\u{FE7A}' | '\u{FE7C}'
26        | '\u{FE7E}' => true,
27        _ => unicode_ident::is_xid_continue(c),
28    }
29}
30
31/// Returns whether a string is a valid JavaScript identifier.
32/// Defined at https://tc39.es/ecma262/#prod-IdentifierName.
33pub fn is_valid_ident(name: &str) -> bool {
34    !name.is_empty()
35        && name.chars().enumerate().all(|(i, char)| {
36            if i == 0 {
37                is_id_start(char) || char == '$' || char == '_'
38            } else {
39                is_id_continue(char) || char == '$' || char == '\u{200C}' || char == '\u{200D}'
40            }
41        })
42}