serde_firestore_value/typ/
function.rs1#[cfg(feature = "btree-map")]
2use std::collections::BTreeMap;
3#[cfg(feature = "hash-map")]
4use std::collections::HashMap;
5
6use super::private::{ValueMapSeed, ValueVecSeed, ValueWrapper};
7use crate::google::firestore::v1::Value;
8
9#[derive(Clone, Debug, PartialEq)]
15pub struct Function {
16 pub name: String,
18 pub args: Vec<Value>,
20 #[cfg(feature = "btree-map")]
22 pub options: BTreeMap<String, Value>,
23 #[cfg(feature = "hash-map")]
25 pub options: HashMap<String, Value>,
26}
27
28impl Function {
29 pub(crate) const FIELDS: &'static [&'static str] = &["name", "args", "options"];
30 pub(crate) const NAME: &'static str = "$__serde-firestore-value_private_function";
31}
32
33impl<'de> serde::Deserialize<'de> for Function {
34 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
35 where
36 D: serde::Deserializer<'de>,
37 {
38 deserializer.deserialize_struct(Self::NAME, Self::FIELDS, FunctionVisitor)
39 }
40}
41
42impl serde::Serialize for Function {
43 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
44 where
45 S: serde::Serializer,
46 {
47 use serde::ser::SerializeStruct;
48
49 let mut state = serializer.serialize_struct(Self::NAME, Self::FIELDS.len())?;
50 state.serialize_field("name", &self.name)?;
51 state.serialize_field(
52 "args",
53 &self.args.iter().map(ValueWrapper).collect::<Vec<_>>(),
54 )?;
55 state.serialize_field(
56 "options",
57 &self
58 .options
59 .iter()
60 .map(|(k, v)| (k.as_str(), ValueWrapper(v)))
61 .collect::<HashMap<_, _>>(),
62 )?;
63 state.end()
64 }
65}
66
67struct FunctionVisitor;
68
69impl<'de> serde::de::Visitor<'de> for FunctionVisitor {
70 type Value = Function;
71
72 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
73 formatter.write_str("a Function struct")
74 }
75
76 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
77 where
78 A: serde::de::MapAccess<'de>,
79 {
80 let mut name: Option<String> = None;
81 let mut args: Option<Vec<Value>> = None;
82 #[cfg(feature = "btree-map")]
83 let mut options: Option<BTreeMap<String, Value>> = None;
84 #[cfg(feature = "hash-map")]
85 let mut options: Option<HashMap<String, Value>> = None;
86
87 while let Some(key) = map.next_key::<String>()? {
88 match key.as_str() {
89 "name" => {
90 if name.is_some() {
91 return Err(serde::de::Error::duplicate_field("name"));
92 }
93 name = Some(map.next_value()?);
94 }
95 "args" => {
96 if args.is_some() {
97 return Err(serde::de::Error::duplicate_field("args"));
98 }
99 args = Some(map.next_value_seed(ValueVecSeed)?);
100 }
101 "options" => {
102 if options.is_some() {
103 return Err(serde::de::Error::duplicate_field("options"));
104 }
105 options = Some(map.next_value_seed(ValueMapSeed)?);
106 }
107 _ => {
108 let _: serde::de::IgnoredAny = map.next_value()?;
109 }
110 }
111 }
112
113 let name = name.ok_or_else(|| serde::de::Error::missing_field("name"))?;
114 let args = args.ok_or_else(|| serde::de::Error::missing_field("args"))?;
115 let options = options.ok_or_else(|| serde::de::Error::missing_field("options"))?;
116
117 Ok(Function {
118 name,
119 args,
120 options,
121 })
122 }
123}