Skip to main content

mpl_lang/
enc_regex.rs

1//! encoding for regular expressions.
2use std::{hash, ops::Deref};
3
4use regex::Regex;
5#[cfg(feature = "wasm")]
6use tsify::Tsify;
7
8/// A wrapper around `regex::Regex` that can be serialized and deserialized via bincode
9#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
10#[cfg_attr(feature = "wasm", derive(Tsify))]
11#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
12pub struct EncodableRegex(
13    #[serde(with = "serde_regex")]
14    #[cfg_attr(feature = "wasm", tsify(type = "RegExp"))]
15    Regex,
16);
17
18impl PartialEq for EncodableRegex {
19    fn eq(&self, other: &Self) -> bool {
20        self.0.as_str() == other.0.as_str()
21    }
22}
23
24impl hash::Hash for EncodableRegex {
25    fn hash<H: hash::Hasher>(&self, state: &mut H) {
26        self.0.as_str().hash(state);
27    }
28}
29
30impl EncodableRegex {
31    /// Creates a new `EncodableRegex` from a regex pattern.
32    pub fn new<S: AsRef<str>>(pattern: S) -> Result<Self, regex::Error> {
33        Regex::new(pattern.as_ref()).map(EncodableRegex)
34    }
35}
36
37impl From<Regex> for EncodableRegex {
38    fn from(regex: Regex) -> Self {
39        EncodableRegex(regex)
40    }
41}
42impl AsRef<Regex> for EncodableRegex {
43    fn as_ref(&self) -> &Regex {
44        &self.0
45    }
46}
47
48impl Deref for EncodableRegex {
49    type Target = Regex;
50
51    fn deref(&self) -> &Self::Target {
52        &self.0
53    }
54}
55
56#[cfg(feature = "bincode")]
57mod bincode_impls {
58    use super::{EncodableRegex, Regex};
59
60    impl bincode::Encode for EncodableRegex {
61        fn encode<E: bincode::enc::Encoder>(
62            &self,
63            encoder: &mut E,
64        ) -> Result<(), bincode::error::EncodeError> {
65            self.0.as_str().encode(encoder)
66        }
67    }
68
69    impl<Context> bincode::Decode<Context> for EncodableRegex {
70        fn decode<D: bincode::de::Decoder>(
71            decoder: &mut D,
72        ) -> Result<Self, bincode::error::DecodeError> {
73            let regex_str: String = bincode::Decode::decode(decoder)?;
74            Regex::new(&regex_str)
75                .map(EncodableRegex)
76                .map_err(|_| bincode::error::DecodeError::Other("Invalid regex"))
77        }
78    }
79    bincode::impl_borrow_decode!(EncodableRegex);
80}