From d51c6c005aaac90329f61baa20821fafc96b841a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Eertmans?= Date: Sun, 1 Jan 2023 14:28:22 +0100 Subject: [PATCH] globset: permit deserializing Glob from String Closes #2386, Closes #2388 --- crates/globset/src/serde_impl.rs | 58 +++++++++++++++++++++++++++++--- 1 file 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,19 +14,67 @@ 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(self, v: &str) -> Result + where + E: Error, + { + Glob::new(v).map_err(serde::de::Error::custom) + } +} + impl<'de> Deserialize<'de> for Glob { fn deserialize>( deserializer: D, ) -> Result { - 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 = + 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 = 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::>(&string); + + assert!(map.is_err()); + } + #[test] fn glob_json_works() { let test_glob = Glob::new("src/**/*.rs").unwrap();