ig_client/presentation/
serialization.rs

1/// Module for handling the conversion between string and optional float values
2///
3/// This module provides serialization and deserialization functions for converting
4/// between `Option<f64>` and string representations used in the IG Markets API.
5pub mod string_as_float_opt {
6    use serde::{self, Deserialize, Deserializer, Serializer};
7    use serde_json::Value;
8
9    /// Serializes an optional float value to its string representation
10    ///
11    /// # Arguments
12    /// * `value` - The optional float value to serialize
13    /// * `serializer` - The serializer to use
14    ///
15    /// # Returns
16    /// A Result containing the serialized value or an error
17    pub fn serialize<S>(value: &Option<f64>, serializer: S) -> Result<S::Ok, S::Error>
18    where
19        S: Serializer,
20    {
21        match value {
22            Some(v) => serializer.serialize_f64(*v), // Serializa como nĂºmero
23            None => serializer.serialize_none(),
24        }
25    }
26
27    /// Deserializes a string representation to an optional float value
28    ///
29    /// # Arguments
30    /// * `deserializer` - The deserializer to use
31    ///
32    /// # Returns
33    /// A Result containing the deserialized optional float value or an error
34    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<f64>, D::Error>
35    where
36        D: Deserializer<'de>,
37    {
38        let value = Value::deserialize(deserializer)?;
39
40        match value {
41            Value::Null => Ok(None),
42            Value::Number(num) => {
43                if let Some(float) = num.as_f64() {
44                    Ok(Some(float))
45                } else {
46                    Err(serde::de::Error::custom("Expected a float"))
47                }
48            }
49            Value::String(s) => {
50                if s.is_empty() {
51                    return Ok(None);
52                }
53                s.parse::<f64>().map(Some).map_err(|_| {
54                    serde::de::Error::custom(format!("Failed to parse string as float: {s}"))
55                })
56            }
57            _ => Err(serde::de::Error::custom("Expected null, number or string")),
58        }
59    }
60}
61
62/// Module for handling the conversion between string and optional boolean values
63///
64/// This module provides serialization and deserialization functions for converting
65/// between `Option<bool>` and string representations ("0" and "1") used in the IG Markets API.
66pub mod string_as_bool_opt {
67    use serde::{self, Deserialize, Deserializer, Serializer};
68
69    /// Serializes an optional boolean value to its string representation
70    ///
71    /// Converts true to "1" and false to "0"
72    ///
73    /// # Arguments
74    /// * `value` - The optional boolean value to serialize
75    /// * `serializer` - The serializer to use
76    ///
77    /// # Returns
78    /// A Result containing the serialized value or an error
79    pub fn serialize<S>(value: &Option<bool>, serializer: S) -> Result<S::Ok, S::Error>
80    where
81        S: Serializer,
82    {
83        match value {
84            Some(v) => {
85                let s = if *v { "1" } else { "0" };
86                serializer.serialize_str(s)
87            }
88            None => serializer.serialize_none(),
89        }
90    }
91
92    /// Deserializes a string representation to an optional boolean value
93    ///
94    /// Converts "1" to true and "0" to false
95    ///
96    /// # Arguments
97    /// * `deserializer` - The deserializer to use
98    ///
99    /// # Returns
100    /// A Result containing the deserialized optional boolean value or an error
101    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<bool>, D::Error>
102    where
103        D: Deserializer<'de>,
104    {
105        let opt = Option::<String>::deserialize(deserializer)?;
106        match opt {
107            Some(s) => {
108                // Handle empty strings as None
109                if s.is_empty() {
110                    return Ok(None);
111                }
112                match s.as_str() {
113                    "0" => Ok(Some(false)),
114                    "1" => Ok(Some(true)),
115                    _ => Err(serde::de::Error::custom(format!(
116                        "Invalid boolean value: {s}"
117                    ))),
118                }
119            }
120            None => Ok(None),
121        }
122    }
123}
124
125/// Module for handling empty strings as None in `Option<String>` fields
126///
127/// This module provides serialization and deserialization functions for converting
128/// between empty strings and None values in `Option<String>` fields.
129pub mod option_string_empty_as_none {
130    use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
131
132    /// Serializes an optional string value, treating empty strings as None
133    ///
134    /// # Arguments
135    /// * `value` - The optional string value to serialize
136    /// * `serializer` - The serializer to use
137    ///
138    /// # Returns
139    /// A Result containing the serialized value or an error
140    pub fn serialize<S>(value: &Option<String>, serializer: S) -> Result<S::Ok, S::Error>
141    where
142        S: Serializer,
143    {
144        match value {
145            Some(s) if s.is_empty() => serializer.serialize_none(),
146            _ => value.serialize(serializer),
147        }
148    }
149
150    /// Deserializes a value to an optional string, treating empty strings as None
151    ///
152    /// # Arguments
153    /// * `deserializer` - The deserializer to use
154    ///
155    /// # Returns
156    /// A Result containing the deserialized optional string value or an error
157    pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
158    where
159        D: Deserializer<'de>,
160    {
161        let opt = Option::<String>::deserialize(deserializer)?;
162        match opt {
163            Some(s) if s.is_empty() => Ok(None),
164            _ => Ok(opt),
165        }
166    }
167}