// extern crate serde; // extern crate regex; // use serde::{Deserialize, Serialize}; // #[derive(Clone, Debug, Deserialize, Serialize)] // #[serde(transparent)] // pub struct Regex(regex::Regex); // #[derive(Clone, Debug, Deserialize, Serialize)] // #[serde(remote = "regex::Regex")] // pub struct RegexDef{ // #[serde(getter = "regex::Regex::to_string")] // r: String // } use std::{fmt, ops}; #[derive(Clone, Debug)] pub struct Regex(regex::Regex); impl Regex { pub fn new(s: &str) -> Self { Self(regex::Regex::new(s).unwrap()) } pub fn as_str(&self) -> &str { self.0.as_str() } pub fn to_string(&self) -> String { self.0.to_string() } } 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 {}