diff options
author | David Tolnay <dtolnay@gmail.com> | 2023-07-26 16:51:22 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-26 19:51:22 -0400 |
commit | 31d3f16254ec3f0c993d05be8f62dc81fc663406 (patch) | |
tree | be03114b4196cc32559bc08e53dea069003f6ba7 | |
parent | 304a60e8e9d4b2a42dc3dfb1ba4cef6d7bf92515 (diff) |
api: impl Deserialize for GlobSet
PR #2569
-rw-r--r-- | crates/globset/src/serde_impl.rs | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/crates/globset/src/serde_impl.rs b/crates/globset/src/serde_impl.rs index d3777c21..88b1574d 100644 --- a/crates/globset/src/serde_impl.rs +++ b/crates/globset/src/serde_impl.rs @@ -1,9 +1,9 @@ use serde::{ - de::{Error, Visitor}, + de::{Error, SeqAccess, Visitor}, {Deserialize, Deserializer, Serialize, Serializer}, }; -use crate::Glob; +use crate::{Glob, GlobSet, GlobSetBuilder}; impl Serialize for Glob { fn serialize<S: Serializer>( @@ -16,7 +16,7 @@ impl Serialize for Glob { struct GlobVisitor; -impl<'a> Visitor<'a> for GlobVisitor { +impl<'de> Visitor<'de> for GlobVisitor { type Value = Glob; fn expecting( @@ -42,11 +42,43 @@ impl<'de> Deserialize<'de> for Glob { } } +struct GlobSetVisitor; + +impl<'de> Visitor<'de> for GlobSetVisitor { + type Value = GlobSet; + + fn expecting( + &self, + formatter: &mut std::fmt::Formatter, + ) -> std::fmt::Result { + formatter.write_str("an array of glob patterns") + } + + fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error> + where + A: SeqAccess<'de>, + { + let mut builder = GlobSetBuilder::new(); + while let Some(glob) = seq.next_element()? { + builder.add(glob); + } + builder.build().map_err(serde::de::Error::custom) + } +} + +impl<'de> Deserialize<'de> for GlobSet { + fn deserialize<D: Deserializer<'de>>( + deserializer: D, + ) -> Result<Self, D::Error> { + deserializer.deserialize_seq(GlobSetVisitor) + } +} + #[cfg(test)] mod tests { use std::collections::HashMap; - use crate::Glob; + use crate::{Glob, GlobSet}; #[test] fn glob_deserialize_borrowed() { @@ -85,4 +117,12 @@ mod tests { let de: Glob = serde_json::from_str(&ser).unwrap(); assert_eq!(test_glob, de); } + + #[test] + fn glob_set_deserialize() { + let j = r#" ["src/**/*.rs", "README.md"] "#; + let set: GlobSet = serde_json::from_str(j).unwrap(); + assert!(set.is_match("src/lib.rs")); + assert!(!set.is_match("Cargo.lock")); + } } |