use std::{fmt, ops}; #[derive(Clone, Debug)] pub struct Regex(regex::Regex); impl Regex { /// Create a new Regex wrapper around regex::Regex; /// /// # Arguments /// /// * `s` - string litteral from which to create the new Regex pub fn new(s: &str) -> Self { Self(regex::Regex::new(s).unwrap()) } /// Returns a string literal representation of the Regex pub fn as_str(&self) -> &str { self.0.as_str() } } use std::hash::{Hash, Hasher}; impl Hash for Regex { fn hash(&self, state: &mut H) { self.0.as_str().hash(state); } } impl ops::Deref for Regex { type Target = regex::Regex; fn deref(&self) -> ®ex::Regex { &self.0 } } impl<'de> serde::Deserialize<'de> for Regex { fn deserialize(de: D) -> Result where D: serde::Deserializer<'de>, { use serde::de::{Error, Visitor}; struct RegexVisitor; impl<'de> Visitor<'de> for RegexVisitor { type Value = Regex; fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("a regular expression pattern") } fn visit_str(self, v: &str) -> Result { regex::Regex::new(v) .map(Regex) .map_err(|err| E::custom(err.to_string())) } } de.deserialize_str(RegexVisitor) } } use serde::{Serialize, Serializer}; impl Serialize for Regex { fn serialize(&self, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(self.0.as_str()) } } impl PartialEq for Regex { fn eq(&self, other: &Self) -> bool { self.0.to_string() == other.0.to_string() } } impl Eq for Regex {}