1mod intmap;
2mod nf;
3mod spec;
4mod utils;
5
6pub use nf::{nfc, nfd};
7pub use spec::{
8 Label, Token, TokenizeOptions, ens_beautify, ens_emoji, ens_normalize, ens_normalize_fragment,
9 ens_split, ens_tokenize, ens_tokenize_with_options, is_combining_mark, should_escape,
10};
11pub use utils::{EnsError, Result, explode_cp, quote_cp, safe_str_from_cps, str_from_cps};
12
13pub fn normalize(name: &str) -> Result<String> {
14 ens_normalize(name)
15}
16
17#[cfg(feature = "wasm")]
18mod wasm {
19 use crate::{EnsError, Token};
20 use serde_json::{Value, json};
21 use wasm_bindgen::prelude::*;
22
23 fn js_error(err: EnsError) -> JsValue {
24 JsValue::from_str(err.message())
25 }
26
27 fn to_js<T: serde::Serialize>(value: &T) -> std::result::Result<JsValue, JsValue> {
28 let serializer = serde_wasm_bindgen::Serializer::new().serialize_maps_as_objects(true);
29 value
30 .serialize(&serializer)
31 .map_err(|err| JsValue::from_str(&err.to_string()))
32 }
33
34 fn token_to_value(token: &Token) -> Value {
35 match token {
36 Token::Stop { cp } => json!({ "type": "stop", "cp": cp }),
37 Token::Disallowed { cp } => json!({ "type": "disallowed", "cp": cp }),
38 Token::Ignored { cp } => json!({ "type": "ignored", "cp": cp }),
39 Token::Valid { cps } => json!({ "type": "valid", "cps": cps }),
40 Token::Mapped { cp, cps } => json!({ "type": "mapped", "cp": cp, "cps": cps }),
41 Token::Emoji { input, cps, emoji } => {
42 json!({ "type": "emoji", "input": input, "cps": cps, "emoji": emoji })
43 }
44 Token::Nfc {
45 input,
46 tokens0,
47 cps,
48 tokens,
49 } => json!({
50 "type": "nfc",
51 "input": input,
52 "tokens0": tokens0.iter().map(token_to_value).collect::<Vec<_>>(),
53 "cps": cps,
54 "tokens": tokens.iter().map(token_to_value).collect::<Vec<_>>()
55 }),
56 }
57 }
58
59 #[wasm_bindgen(js_name = ens_normalize)]
60 pub fn ens_normalize_js(name: &str) -> std::result::Result<String, JsValue> {
61 crate::ens_normalize(name).map_err(js_error)
62 }
63
64 #[wasm_bindgen(js_name = ens_beautify)]
65 pub fn ens_beautify_js(name: &str) -> std::result::Result<String, JsValue> {
66 crate::ens_beautify(name).map_err(js_error)
67 }
68
69 #[wasm_bindgen(js_name = ens_normalize_fragment)]
70 pub fn ens_normalize_fragment_js(
71 fragment: &str,
72 decompose: bool,
73 ) -> std::result::Result<String, JsValue> {
74 crate::ens_normalize_fragment(fragment, decompose).map_err(js_error)
75 }
76
77 #[wasm_bindgen(js_name = ens_tokenize)]
78 pub fn ens_tokenize_js(name: &str) -> std::result::Result<JsValue, JsValue> {
79 let tokens = crate::ens_tokenize(name)
80 .iter()
81 .map(token_to_value)
82 .collect::<Vec<_>>();
83 to_js(&tokens)
84 }
85
86 #[wasm_bindgen(js_name = ens_emoji)]
87 pub fn ens_emoji_js() -> std::result::Result<JsValue, JsValue> {
88 to_js(&crate::ens_emoji())
89 }
90
91 #[wasm_bindgen(js_name = nfc)]
92 pub fn nfc_js(cps: JsValue) -> std::result::Result<JsValue, JsValue> {
93 let cps: Vec<u32> = serde_wasm_bindgen::from_value(cps)
94 .map_err(|err| JsValue::from_str(&err.to_string()))?;
95 to_js(&crate::nfc(&cps))
96 }
97
98 #[wasm_bindgen(js_name = nfd)]
99 pub fn nfd_js(cps: JsValue) -> std::result::Result<JsValue, JsValue> {
100 let cps: Vec<u32> = serde_wasm_bindgen::from_value(cps)
101 .map_err(|err| JsValue::from_str(&err.to_string()))?;
102 to_js(&crate::nfd(&cps))
103 }
104}