wasm_bindgen_shared/
identifier.rs1use alloc::string::String;
2
3fn is_id_start(c: char) -> bool {
9 match c {
10 '\u{037A}' | '\u{0E33}' | '\u{0EB3}' | '\u{309B}' | '\u{309C}' | '\u{FC5E}'
11 | '\u{FC5F}' | '\u{FC60}' | '\u{FC61}' | '\u{FC62}' | '\u{FC63}' | '\u{FDFA}'
12 | '\u{FDFB}' | '\u{FE70}' | '\u{FE72}' | '\u{FE74}' | '\u{FE76}' | '\u{FE78}'
13 | '\u{FE7A}' | '\u{FE7C}' | '\u{FE7E}' | '\u{FF9E}' | '\u{FF9F}' => true,
14 '$' | '_' => true,
15 _ => unicode_ident::is_xid_start(c),
16 }
17}
18
19fn is_id_continue(c: char) -> bool {
25 match c {
26 '\u{037A}' | '\u{309B}' | '\u{309C}' | '\u{FC5E}' | '\u{FC5F}' | '\u{FC60}'
27 | '\u{FC61}' | '\u{FC62}' | '\u{FC63}' | '\u{FDFA}' | '\u{FDFB}' | '\u{FE70}'
28 | '\u{FE72}' | '\u{FE74}' | '\u{FE76}' | '\u{FE78}' | '\u{FE7A}' | '\u{FE7C}'
29 | '\u{FE7E}' => true,
30 '$' | '\u{200C}' | '\u{200D}' => true,
31 _ => unicode_ident::is_xid_continue(c),
32 }
33}
34
35fn maybe_valid_chars(name: &str) -> impl Iterator<Item = Option<char>> + '_ {
36 let mut chars = name.chars();
37 core::iter::once(chars.next().filter(|&c| is_id_start(c))).chain(chars.map(|c| {
41 if is_id_continue(c) {
42 Some(c)
43 } else {
44 None
45 }
46 }))
47}
48
49pub fn is_valid_ident(name: &str) -> bool {
52 maybe_valid_chars(name).all(|opt| opt.is_some())
53}
54
55pub fn to_valid_ident(name: &str) -> String {
58 maybe_valid_chars(name)
59 .map(|opt| opt.unwrap_or('_'))
60 .collect()
61}