Skip to main content

proto_types/
field_mask.rs

1use 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	/// Creates a new instance.
51	#[must_use]
52	#[inline]
53	pub const fn new(paths: Vec<String>) -> Self {
54		Self { paths }
55	}
56
57	/// Checks if a path is present in the list.
58	#[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}