1 use std::collections::BTreeSet; 2 use std::fmt; 3 4 use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer}; 5 use serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor}; 6 use serde::ser::{Serialize, SerializeStruct, Serializer}; 7 8 #[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Clone)] 9 pub(crate) struct Glob { 10 pub(crate) allow_empty: bool, 11 pub(crate) include: BTreeSet<String>, 12 pub(crate) exclude: BTreeSet<String>, 13 } 14 15 impl Glob { new_rust_srcs(allow_empty: bool) -> Self16 pub(crate) fn new_rust_srcs(allow_empty: bool) -> Self { 17 Self { 18 allow_empty, 19 include: BTreeSet::from(["**/*.rs".to_owned()]), 20 exclude: BTreeSet::new(), 21 } 22 } 23 has_any_include(&self) -> bool24 pub(crate) fn has_any_include(&self) -> bool { 25 self.include.is_empty() 26 // Note: self.exclude intentionally not considered. A glob is empty if 27 // there are no included globs. A glob cannot have only excludes. 28 } 29 } 30 31 impl Serialize for Glob { serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer,32 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 33 where 34 S: Serializer, 35 { 36 let has_exclude = !self.exclude.is_empty(); 37 let len = 2 + if has_exclude { 1 } else { 0 }; 38 39 // Serialize as glob(allow_empty = False, include = [...], exclude = [...]). 40 let mut call = serializer.serialize_struct("glob", len)?; 41 call.serialize_field("allow_empty", &self.allow_empty)?; 42 call.serialize_field("include", &self.include)?; 43 if has_exclude { 44 call.serialize_field("exclude", &self.exclude)?; 45 } 46 call.end() 47 } 48 } 49 50 struct GlobVisitor; 51 52 impl<'de> Deserialize<'de> for Glob { deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,53 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 54 where 55 D: Deserializer<'de>, 56 { 57 deserializer.deserialize_any(GlobVisitor) 58 } 59 } 60 61 impl<'de> Visitor<'de> for GlobVisitor { 62 type Value = Glob; 63 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result64 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 65 formatter.write_str("glob") 66 } 67 68 // Deserialize ["included","globs","only"] visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error> where A: SeqAccess<'de>,69 fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error> 70 where 71 A: SeqAccess<'de>, 72 { 73 Ok(Glob { 74 // At time of writing the default value of allow_empty is true. 75 // We may want to change this if the default changes in Bazel. 76 allow_empty: true, 77 include: BTreeSet::deserialize(SeqAccessDeserializer::new(seq))?, 78 exclude: BTreeSet::new(), 79 }) 80 } 81 82 // Deserialize {"include":["included","globs"],"exclude":["excluded","globs"]} visit_map<A>(self, map: A) -> Result<Self::Value, A::Error> where A: MapAccess<'de>,83 fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error> 84 where 85 A: MapAccess<'de>, 86 { 87 fn default_true() -> bool { 88 true 89 } 90 91 #[derive(serde::Deserialize)] 92 struct GlobMap { 93 #[serde(default = "default_true")] 94 allow_empty: bool, 95 include: BTreeSet<String>, 96 #[serde(default)] 97 exclude: BTreeSet<String>, 98 } 99 100 let glob_map = GlobMap::deserialize(MapAccessDeserializer::new(map))?; 101 Ok(Glob { 102 allow_empty: glob_map.allow_empty, 103 include: glob_map.include, 104 exclude: glob_map.exclude, 105 }) 106 } 107 } 108