proto_types/
field_mask.rs1use core::ops::{Deref, DerefMut};
2
3use crate::*;
4
5impl Deref for FieldMask {
6 type Target = [String];
7
8 #[inline]
9 fn deref(&self) -> &Self::Target {
10 &self.paths
11 }
12}
13
14impl DerefMut for FieldMask {
15 #[inline]
16 fn deref_mut(&mut self) -> &mut Self::Target {
17 &mut self.paths
18 }
19}
20
21impl IntoIterator for FieldMask {
22 type Item = String;
23 type IntoIter = alloc::vec::IntoIter<String>;
24
25 #[inline]
26 fn into_iter(self) -> Self::IntoIter {
27 self.paths.into_iter()
28 }
29}
30
31impl<'a> IntoIterator for &'a FieldMask {
32 type Item = &'a String;
33 type IntoIter = core::slice::Iter<'a, String>;
34
35 #[inline]
36 fn into_iter(self) -> Self::IntoIter {
37 self.paths.iter()
38 }
39}
40
41impl FromIterator<String> for FieldMask {
42 fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
43 Self {
44 paths: iter.into_iter().collect(),
45 }
46 }
47}
48
49impl FieldMask {
50 #[must_use]
52 #[inline]
53 pub const fn new(paths: Vec<String>) -> Self {
54 Self { paths }
55 }
56
57 #[must_use]
59 #[inline]
60 pub fn contains_path(&self, path: &str) -> bool {
61 self.paths.iter().any(|p| p == path)
62 }
63
64 #[deprecated = "You can use .push() directly to leverage the DerefMut impl"]
65 pub fn add_path(&mut self, path: &str) {
66 self.paths.push(path.to_string());
67 }
68}
69
70#[cfg(feature = "serde")]
71mod serde_impls {
72 use super::*;
73
74 use core::fmt;
75
76 use serde::{Deserialize, Serialize};
77
78 use crate::FieldMask;
79 impl Serialize for FieldMask {
80 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
81 where
82 S: serde::Serializer,
83 {
84 let joined_paths = self.paths.join(",");
85 serializer.serialize_str(&joined_paths)
86 }
87 }
88
89 impl<'de> Deserialize<'de> for FieldMask {
90 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91 where
92 D: serde::Deserializer<'de>,
93 {
94 struct FieldMaskVisitor;
95
96 impl serde::de::Visitor<'_> for FieldMaskVisitor {
97 type Value = FieldMask;
98
99 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
100 formatter.write_str("a comma-separated string of field paths")
101 }
102
103 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
104 where
105 E: serde::de::Error,
106 {
107 if value.is_empty() {
108 return Ok(FieldMask { paths: Vec::new() });
109 }
110
111 let paths: Vec<String> = value
112 .split(",")
113 .map(|s| s.trim().to_string())
114 .collect();
115
116 Ok(FieldMask { paths })
117 }
118 }
119
120 deserializer.deserialize_str(FieldMaskVisitor)
121 }
122 }
123}