Skip to main content

serde_firestore_value/typ/
function.rs

1#[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/// Function
10///
11/// `functionValue` inner type.
12///
13/// <https://firebase.google.com/docs/firestore/reference/rest/Shared.Types/ArrayValue#Value>
14#[derive(Clone, Debug, PartialEq)]
15pub struct Function {
16    /// Required. The name of the function to evaluate.
17    pub name: String,
18    /// Optional. Ordered list of arguments the given function expects.
19    pub args: Vec<Value>,
20    /// Optional. Optional named arguments that certain functions may support.
21    #[cfg(feature = "btree-map")]
22    pub options: BTreeMap<String, Value>,
23    /// Optional. Optional named arguments that certain functions may support.
24    #[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}