Skip to main content

ens_normalize/
lib.rs

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}