• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

geo-engine / geoengine / 3929938005

pending completion
3929938005

push

github

GitHub
Merge #713

84930 of 96741 relevant lines covered (87.79%)

79640.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.16
/operators/src/util/input/string_or_number.rs
1
use std::convert::TryFrom;
2

3
use crate::error;
4
use serde::de::Visitor;
5
use serde::{Deserialize, Deserializer, Serialize, Serializer};
6

7
/// A type that allows use inputs to be either strings or numbers
8
#[derive(Debug, Clone, PartialEq)]
3✔
9
pub enum StringOrNumber {
10
    String(String),
11
    Float(f64),
12
    Int(i64),
13
}
14

15
impl Serialize for StringOrNumber {
16
    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
3✔
17
    where
3✔
18
        S: Serializer,
3✔
19
    {
3✔
20
        match self {
3✔
21
            StringOrNumber::String(v) => serializer.serialize_str(v),
1✔
22
            StringOrNumber::Float(v) => serializer.serialize_f64(*v),
1✔
23
            StringOrNumber::Int(v) => serializer.serialize_i64(*v),
1✔
24
        }
25
    }
3✔
26
}
27

28
impl<'de> Deserialize<'de> for StringOrNumber {
29
    fn deserialize<D>(deserializer: D) -> Result<Self, <D as Deserializer<'de>>::Error>
17✔
30
    where
17✔
31
        D: Deserializer<'de>,
17✔
32
    {
17✔
33
        deserializer.deserialize_any(StringOrNumberDeserializer)
17✔
34
    }
17✔
35
}
36

37
struct StringOrNumberDeserializer;
38
impl<'de> Visitor<'de> for StringOrNumberDeserializer {
39
    type Value = StringOrNumber;
40

41
    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
×
42
        formatter.write_str("an integer, float or string")
×
43
    }
×
44

45
    fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
8✔
46
    where
8✔
47
        E: serde::de::Error,
8✔
48
    {
8✔
49
        Ok(StringOrNumber::Int(v))
8✔
50
    }
8✔
51

52
    fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
8✔
53
    where
8✔
54
        E: serde::de::Error,
8✔
55
    {
8✔
56
        self.visit_i64(v as i64)
8✔
57
    }
8✔
58

59
    fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
5✔
60
    where
5✔
61
        E: serde::de::Error,
5✔
62
    {
5✔
63
        Ok(StringOrNumber::Float(v))
5✔
64
    }
5✔
65

66
    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
4✔
67
    where
4✔
68
        E: serde::de::Error,
4✔
69
    {
4✔
70
        self.visit_string(v.to_string())
4✔
71
    }
4✔
72

73
    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
4✔
74
    where
4✔
75
        E: serde::de::Error,
4✔
76
    {
4✔
77
        Ok(StringOrNumber::String(v))
4✔
78
    }
4✔
79
}
80

81
impl From<f64> for StringOrNumber {
82
    fn from(v: f64) -> Self {
×
83
        StringOrNumber::Float(v)
×
84
    }
×
85
}
86

87
impl From<i64> for StringOrNumber {
88
    fn from(v: i64) -> Self {
×
89
        StringOrNumber::Int(v)
×
90
    }
×
91
}
92

93
impl From<String> for StringOrNumber {
94
    fn from(v: String) -> Self {
×
95
        StringOrNumber::String(v)
×
96
    }
×
97
}
98

99
impl From<&str> for StringOrNumber {
100
    fn from(v: &str) -> Self {
×
101
        StringOrNumber::from(v.to_string())
×
102
    }
×
103
}
104

105
impl TryFrom<StringOrNumber> for f64 {
106
    type Error = error::Error;
107

108
    fn try_from(value: StringOrNumber) -> Result<Self, Self::Error> {
3✔
109
        Self::try_from(&value)
3✔
110
    }
3✔
111
}
112

113
impl TryFrom<&StringOrNumber> for f64 {
114
    type Error = error::Error;
115

116
    fn try_from(value: &StringOrNumber) -> Result<Self, Self::Error> {
4✔
117
        match value {
4✔
118
            StringOrNumber::String(_) => Err(error::Error::InvalidType {
1✔
119
                expected: "number".to_string(),
1✔
120
                found: "string".to_string(),
1✔
121
            }),
1✔
122
            StringOrNumber::Float(v) => Ok(*v),
2✔
123
            StringOrNumber::Int(v) => Ok(*v as f64),
1✔
124
        }
125
    }
4✔
126
}
127

128
impl TryFrom<StringOrNumber> for i64 {
129
    type Error = error::Error;
130

131
    fn try_from(value: StringOrNumber) -> Result<Self, Self::Error> {
3✔
132
        Self::try_from(&value)
3✔
133
    }
3✔
134
}
135

136
impl TryFrom<&StringOrNumber> for i64 {
137
    type Error = error::Error;
138

139
    fn try_from(value: &StringOrNumber) -> Result<Self, Self::Error> {
4✔
140
        match value {
4✔
141
            StringOrNumber::String(_) => Err(error::Error::InvalidType {
1✔
142
                expected: "number".to_string(),
1✔
143
                found: "string".to_string(),
1✔
144
            }),
1✔
145
            StringOrNumber::Float(v) => Ok(*v as i64),
2✔
146
            StringOrNumber::Int(v) => Ok(*v),
1✔
147
        }
148
    }
4✔
149
}
150

151
impl TryFrom<StringOrNumber> for String {
152
    type Error = error::Error;
153

154
    fn try_from(value: StringOrNumber) -> Result<Self, Self::Error> {
4✔
155
        match value {
4✔
156
            StringOrNumber::String(v) => Ok(v),
2✔
157
            StringOrNumber::Float(_) | StringOrNumber::Int(_) => Err(error::Error::InvalidType {
2✔
158
                expected: "string".to_string(),
2✔
159
                found: "number".to_string(),
2✔
160
            }),
2✔
161
        }
162
    }
4✔
163
}
164

165
impl TryFrom<&StringOrNumber> for String {
166
    type Error = error::Error;
167

168
    fn try_from(value: &StringOrNumber) -> Result<Self, Self::Error> {
1✔
169
        Self::try_from(value.clone())
1✔
170
    }
1✔
171
}
172

173
impl<'v> TryFrom<&'v StringOrNumber> for &'v str {
174
    type Error = error::Error;
175

176
    fn try_from(value: &'v StringOrNumber) -> Result<Self, Self::Error> {
×
177
        match value {
×
178
            StringOrNumber::String(v) => Ok(v),
×
179
            StringOrNumber::Float(_) | StringOrNumber::Int(_) => Err(error::Error::InvalidType {
×
180
                expected: "string".to_string(),
×
181
                found: "number".to_string(),
×
182
            }),
×
183
        }
184
    }
×
185
}
186

187
#[cfg(test)]
188
mod tests {
189
    use super::*;
190
    use std::convert::TryFrom;
191

192
    #[test]
1✔
193
    fn serialize() {
1✔
194
        assert_eq!(
1✔
195
            serde_json::to_string(&StringOrNumber::String("foobar".to_string())).unwrap(),
1✔
196
            "\"foobar\""
1✔
197
        );
1✔
198

199
        assert_eq!(
1✔
200
            serde_json::to_string(&StringOrNumber::Float(1337.)).unwrap(),
1✔
201
            "1337.0"
1✔
202
        );
1✔
203

204
        assert_eq!(
1✔
205
            serde_json::to_string(&StringOrNumber::Int(42)).unwrap(),
1✔
206
            "42"
1✔
207
        );
1✔
208
    }
1✔
209

210
    #[test]
1✔
211
    fn deserialize() {
1✔
212
        assert_eq!(
1✔
213
            serde_json::from_str::<StringOrNumber>("\"foobar\"").unwrap(),
1✔
214
            StringOrNumber::String("foobar".to_string())
1✔
215
        );
1✔
216

217
        assert_eq!(
1✔
218
            serde_json::from_str::<StringOrNumber>("1337.0").unwrap(),
1✔
219
            StringOrNumber::Float(1337.)
1✔
220
        );
1✔
221

222
        assert_eq!(
1✔
223
            serde_json::from_str::<StringOrNumber>("42").unwrap(),
1✔
224
            StringOrNumber::Int(42)
1✔
225
        );
1✔
226
    }
1✔
227

228
    #[test]
1✔
229
    #[allow(clippy::float_cmp)]
230
    fn try_into() {
1✔
231
        assert_eq!(
1✔
232
            String::try_from(StringOrNumber::String("foobar".to_string())).unwrap(),
1✔
233
            "foobar".to_string()
1✔
234
        );
1✔
235
        assert_eq!(
1✔
236
            String::try_from(&StringOrNumber::String("foobar".to_string())).unwrap(),
1✔
237
            "foobar"
1✔
238
        );
1✔
239

240
        assert_eq!(f64::try_from(StringOrNumber::Float(1337.)).unwrap(), 1337.);
1✔
241
        assert_eq!(f64::try_from(&StringOrNumber::Float(1337.)).unwrap(), 1337.);
1✔
242

243
        assert_eq!(i64::try_from(StringOrNumber::Float(1337.)).unwrap(), 1337);
1✔
244
        assert_eq!(i64::try_from(&StringOrNumber::Float(1337.)).unwrap(), 1337);
1✔
245

246
        assert_eq!(i64::try_from(StringOrNumber::Int(42)).unwrap(), 42);
1✔
247

248
        assert_eq!(f64::try_from(StringOrNumber::Int(42)).unwrap(), 42.);
1✔
249

250
        assert!(String::try_from(StringOrNumber::Float(1337.)).is_err());
1✔
251
        assert!(String::try_from(StringOrNumber::Int(42)).is_err());
1✔
252

253
        assert!(i64::try_from(StringOrNumber::String("foobar".to_string())).is_err());
1✔
254
        assert!(f64::try_from(StringOrNumber::String("foobar".to_string())).is_err());
1✔
255
    }
1✔
256
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc