floating_ui/utils_/
string_union.rs

1use crate::error::Result;
2
3pub trait StringUnion: Sized {
4    fn as_str(&self) -> &str;
5    fn try_from_str(value: &str) -> Result<Self>;
6}
7
8macro_rules! string_union {
9    ($name:ident {
10        $($str:literal => $variant:ident),*
11    }) => {
12        #[derive(Clone)]
13        pub enum $name {
14            $($variant),*
15        }
16
17        impl crate::utils_::StringUnion for $name {
18            fn as_str(&self) -> &str {
19                match self {
20                    $(Self::$variant => $str,)*
21                }
22            }
23
24            fn try_from_str(value: &str) -> crate::Result<Self> {
25                match value {
26                    $($str => Ok(Self::$variant),)*
27                    _ => Err(crate::Error::InvalidValue(value.to_string(), stringify!($name))),
28                }
29            }
30        }
31
32        impl ToString for $name {
33            fn to_string(&self) -> String {
34                self.as_str().to_string()
35            }
36        }
37
38        impl Into<wasm_bindgen::JsValue> for $name {
39            fn into(self) -> wasm_bindgen::JsValue {
40                self.as_str().into()
41            }
42        }
43
44        impl TryFrom<wasm_bindgen::JsValue> for $name {
45            type Error = crate::Error;
46
47            fn try_from(value: wasm_bindgen::JsValue) -> crate::Result<Self> {
48                let s = match value.as_string() {
49                    Some(s) => s,
50                    None => return Err(crate::Error::InvalidJsValue("value".to_string(), "string")),
51                };
52
53                Self::try_from_str(&s)
54            }
55        }
56    };
57}
58
59pub(crate) use string_union;