diff options
author | Jérome Eertmans <jeertmans@icloud.com> | 2023-01-01 14:28:22 +0100 |
---|---|---|
committer | Andrew Gallant <jamslam@gmail.com> | 2023-07-08 18:52:42 -0400 |
commit | d51c6c005aaac90329f61baa20821fafc96b841a (patch) | |
tree | 8ba850d14d812c73e4894283e77db7e1232659c9 | |
parent | ea058813196dcdf53a51b0a689da0f4170b6ed75 (diff) |
globset: permit deserializing Glob from String
Closes #2386, Closes #2388
-rw-r--r-- | crates/globset/src/serde_impl.rs | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/crates/globset/src/serde_impl.rs b/crates/globset/src/serde_impl.rs index 2004ce84..d3777c21 100644 --- a/crates/globset/src/serde_impl.rs +++ b/crates/globset/src/serde_impl.rs @@ -1,5 +1,7 @@ -use serde::de::Error; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use serde::{ + de::{Error, Visitor}, + {Deserialize, Deserializer, Serialize, Serializer}, +}; use crate::Glob; @@ -12,20 +14,68 @@ impl Serialize for Glob { } } +struct GlobVisitor; + +impl<'a> Visitor<'a> for GlobVisitor { + type Value = Glob; + + fn expecting( + &self, + formatter: &mut std::fmt::Formatter, + ) -> std::fmt::Result { + formatter.write_str("a glob pattern") + } + + fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> + where + E: Error, + { + Glob::new(v).map_err(serde::de::Error::custom) + } +} + impl<'de> Deserialize<'de> for Glob { fn deserialize<D: Deserializer<'de>>( deserializer: D, ) -> Result<Self, D::Error> { - let glob = <&str as Deserialize>::deserialize(deserializer)?; - Glob::new(glob).map_err(D::Error::custom) + deserializer.deserialize_str(GlobVisitor) } } #[cfg(test)] mod tests { + use std::collections::HashMap; + use crate::Glob; #[test] + fn glob_deserialize_borrowed() { + let string = r#"{"markdown": "*.md"}"#; + + let map: HashMap<String, Glob> = + serde_json::from_str(&string).unwrap(); + assert_eq!(map["markdown"], Glob::new("*.md").unwrap()); + } + + #[test] + fn glob_deserialize_owned() { + let string = r#"{"markdown": "*.md"}"#; + + let v: serde_json::Value = serde_json::from_str(&string).unwrap(); + let map: HashMap<String, Glob> = serde_json::from_value(v).unwrap(); + assert_eq!(map["markdown"], Glob::new("*.md").unwrap()); + } + + #[test] + fn glob_deserialize_error() { + let string = r#"{"error": "["}"#; + + let map = serde_json::from_str::<HashMap<String, Glob>>(&string); + + assert!(map.is_err()); + } + + #[test] fn glob_json_works() { let test_glob = Glob::new("src/**/*.rs").unwrap(); |