Coverage Report

Created: 2025-07-02 06:18

/src/bson-rust/src/extjson/models.rs
Line
Count
Source (jump to first uncovered line)
1
//! A module defining serde models for the extended JSON representations of the various BSON types.
2
3
use serde::{
4
    de::{Error as _, Unexpected},
5
    Deserialize,
6
    Serialize,
7
};
8
use std::borrow::Cow;
9
10
use crate::{
11
    base64,
12
    error::{Error, Result},
13
    oid,
14
    raw::serde::CowStr,
15
    spec::BinarySubtype,
16
    Bson,
17
};
18
19
#[derive(Deserialize)]
20
#[serde(deny_unknown_fields)]
21
pub(crate) struct Int32 {
22
    #[serde(rename = "$numberInt")]
23
    value: String,
24
}
25
26
impl Int32 {
27
0
    pub(crate) fn parse(self) -> Result<i32> {
28
0
        self.value.parse().map_err(|_| {
29
0
            Error::invalid_value(Unexpected::Str(self.value.as_str()), &"i32 as a string")
30
0
        })
31
0
    }
32
}
33
34
#[derive(Deserialize, Serialize)]
35
#[serde(deny_unknown_fields)]
36
pub(crate) struct Int64 {
37
    #[serde(rename = "$numberLong")]
38
    value: String,
39
}
40
41
impl Int64 {
42
32.6k
    pub(crate) fn parse(self) -> Result<i64> {
43
32.6k
        self.value.parse().map_err(|_| {
44
2
            Error::invalid_value(Unexpected::Str(self.value.as_str()), &"i64 as a string")
45
32.6k
        })
46
32.6k
    }
47
}
48
49
#[derive(Deserialize)]
50
#[serde(deny_unknown_fields)]
51
pub(crate) struct Double {
52
    #[serde(rename = "$numberDouble")]
53
    value: String,
54
}
55
56
impl Double {
57
0
    pub(crate) fn parse(self) -> Result<f64> {
58
0
        match self.value.as_str() {
59
0
            "Infinity" => Ok(f64::INFINITY),
60
0
            "-Infinity" => Ok(f64::NEG_INFINITY),
61
0
            "NaN" => Ok(f64::NAN),
62
0
            other => other.parse().map_err(|_| {
63
0
                Error::invalid_value(Unexpected::Str(other), &"bson double as string")
64
0
            }),
65
        }
66
0
    }
67
}
68
69
#[derive(Deserialize)]
70
#[serde(deny_unknown_fields)]
71
pub(crate) struct Decimal128 {
72
    #[serde(rename = "$numberDecimal")]
73
    value: String,
74
}
75
76
impl Decimal128 {
77
0
    pub(crate) fn parse(self) -> Result<crate::Decimal128> {
78
0
        self.value.parse().map_err(|_| {
79
0
            Error::invalid_value(Unexpected::Str(&self.value), &"bson decimal128 as string")
80
0
        })
81
0
    }
82
}
83
84
#[derive(Serialize, Deserialize)]
85
#[serde(deny_unknown_fields)]
86
pub(crate) struct ObjectId {
87
    #[serde(rename = "$oid")]
88
    oid: String,
89
}
90
91
impl ObjectId {
92
14.8k
    pub(crate) fn parse(self) -> Result<oid::ObjectId> {
93
14.8k
        oid::ObjectId::parse_str(self.oid.as_str())
94
14.8k
    }
95
}
96
97
impl From<crate::oid::ObjectId> for ObjectId {
98
0
    fn from(id: crate::oid::ObjectId) -> Self {
99
0
        Self { oid: id.to_hex() }
100
0
    }
101
}
102
103
#[derive(Deserialize)]
104
#[serde(deny_unknown_fields)]
105
pub(crate) struct Symbol {
106
    #[serde(rename = "$symbol")]
107
    pub(crate) value: String,
108
}
109
110
#[derive(Deserialize)]
111
#[serde(deny_unknown_fields)]
112
pub(crate) struct Regex {
113
    #[serde(rename = "$regularExpression")]
114
    body: RegexBody,
115
}
116
117
#[derive(Serialize, Deserialize)]
118
#[serde(deny_unknown_fields)]
119
pub(crate) struct RegexBody {
120
    pub(crate) pattern: String,
121
    pub(crate) options: String,
122
}
123
124
impl Regex {
125
0
    pub(crate) fn parse(self) -> crate::Regex {
126
0
        crate::Regex::new(self.body.pattern, self.body.options)
127
0
    }
128
}
129
130
#[derive(Deserialize)]
131
#[serde(deny_unknown_fields)]
132
pub(crate) struct Binary {
133
    #[serde(rename = "$binary")]
134
    pub(crate) body: BinaryBody,
135
}
136
137
#[derive(Deserialize, Serialize)]
138
#[serde(deny_unknown_fields)]
139
pub(crate) struct BinaryBody {
140
    pub(crate) base64: String,
141
142
    #[serde(rename = "subType")]
143
    pub(crate) subtype: String,
144
}
145
146
impl Binary {
147
58.4k
    pub(crate) fn parse(self) -> Result<crate::Binary> {
148
58.4k
        let bytes = base64::decode(self.body.base64.as_str()).map_err(|_| {
149
27
            Error::invalid_value(
150
27
                Unexpected::Str(self.body.base64.as_str()),
151
27
                &"base64 encoded bytes",
152
27
            )
153
58.4k
        })?;
154
155
58.3k
        let subtype = hex::decode(self.body.subtype.as_str()).map_err(|_| {
156
26
            Error::invalid_value(
157
26
                Unexpected::Str(self.body.subtype.as_str()),
158
26
                &"hexadecimal number as a string",
159
26
            )
160
58.3k
        })?;
161
162
58.3k
        if subtype.len() == 1 {
163
58.3k
            Ok(crate::Binary {
164
58.3k
                bytes,
165
58.3k
                subtype: subtype[0].into(),
166
58.3k
            })
167
        } else {
168
8
            Err(Error::invalid_value(
169
8
                Unexpected::Bytes(subtype.as_slice()),
170
8
                &"one byte subtype",
171
8
            ))
172
        }
173
58.4k
    }
174
}
175
176
#[derive(Deserialize)]
177
#[serde(deny_unknown_fields)]
178
pub(crate) struct Uuid {
179
    #[serde(rename = "$uuid")]
180
    pub(crate) value: String,
181
}
182
183
impl Uuid {
184
329
    pub(crate) fn parse(self) -> Result<crate::Binary> {
185
329
        let uuid = uuid::Uuid::parse_str(&self.value).map_err(|_| {
186
315
            Error::invalid_value(
187
315
                Unexpected::Str(&self.value),
188
315
                &"$uuid value does not follow RFC 4122 format regarding length and hyphens",
189
315
            )
190
329
        })?;
191
192
14
        Ok(crate::Binary {
193
14
            subtype: BinarySubtype::Uuid,
194
14
            bytes: uuid.as_bytes().to_vec(),
195
14
        })
196
329
    }
197
}
198
199
#[derive(Deserialize)]
200
#[serde(deny_unknown_fields)]
201
pub(crate) struct JavaScriptCodeWithScope {
202
    #[serde(rename = "$code")]
203
    pub(crate) code: String,
204
205
    #[serde(rename = "$scope")]
206
    #[serde(default)]
207
    pub(crate) scope: Option<serde_json::Map<String, serde_json::Value>>,
208
}
209
210
#[derive(Deserialize)]
211
#[serde(deny_unknown_fields)]
212
pub(crate) struct Timestamp {
213
    #[serde(rename = "$timestamp")]
214
    body: TimestampBody,
215
}
216
217
#[derive(Serialize, Deserialize, Debug)]
218
#[serde(deny_unknown_fields)]
219
pub(crate) struct TimestampBody {
220
    #[serde(serialize_with = "crate::serde_helpers::serialize_u32_as_i64")]
221
    pub(crate) t: u32,
222
223
    #[serde(serialize_with = "crate::serde_helpers::serialize_u32_as_i64")]
224
    pub(crate) i: u32,
225
}
226
227
impl Timestamp {
228
0
    pub(crate) fn parse(self) -> crate::Timestamp {
229
0
        crate::Timestamp {
230
0
            time: self.body.t,
231
0
            increment: self.body.i,
232
0
        }
233
0
    }
234
}
235
236
#[derive(Serialize, Deserialize)]
237
#[serde(deny_unknown_fields)]
238
pub(crate) struct DateTime {
239
    #[serde(rename = "$date")]
240
    pub(crate) body: DateTimeBody,
241
}
242
243
#[derive(Deserialize, Serialize)]
244
#[serde(untagged)]
245
pub(crate) enum DateTimeBody {
246
    Canonical(Int64),
247
    Relaxed(String),
248
    Legacy(i64),
249
}
250
251
impl DateTimeBody {
252
2.97k
    pub(crate) fn from_millis(m: i64) -> Self {
253
2.97k
        DateTimeBody::Canonical(Int64 {
254
2.97k
            value: m.to_string(),
255
2.97k
        })
256
2.97k
    }
257
}
258
259
impl DateTime {
260
39.9k
    pub(crate) fn parse(self) -> Result<crate::DateTime> {
261
39.9k
        match self.body {
262
32.6k
            DateTimeBody::Canonical(date) => {
263
32.6k
                let date = date.parse()?;
264
32.6k
                Ok(crate::DateTime::from_millis(date))
265
            }
266
6.13k
            DateTimeBody::Relaxed(date) => {
267
6.13k
                let datetime = crate::DateTime::parse_rfc3339_str(date.as_str()).map_err(|_| {
268
356
                    Error::invalid_value(
269
356
                        Unexpected::Str(date.as_str()),
270
356
                        &"rfc3339 formatted utc datetime",
271
356
                    )
272
6.13k
                })?;
273
5.77k
                Ok(datetime)
274
            }
275
1.22k
            DateTimeBody::Legacy(ms) => Ok(crate::DateTime::from_millis(ms)),
276
        }
277
39.9k
    }
278
}
279
280
#[derive(Deserialize)]
281
#[serde(deny_unknown_fields)]
282
pub(crate) struct MinKey {
283
    #[serde(rename = "$minKey")]
284
    pub(crate) value: u8,
285
}
286
287
impl MinKey {
288
71.8k
    pub(crate) fn parse(self) -> Result<Bson> {
289
71.8k
        if self.value == 1 {
290
71.8k
            Ok(Bson::MinKey)
291
        } else {
292
10
            Err(Error::invalid_value(
293
10
                Unexpected::Unsigned(self.value as u64),
294
10
                &"value of $minKey should always be 1",
295
10
            ))
296
        }
297
71.8k
    }
298
}
299
300
#[derive(Deserialize)]
301
#[serde(deny_unknown_fields)]
302
pub(crate) struct MaxKey {
303
    #[serde(rename = "$maxKey")]
304
    pub(crate) value: u8,
305
}
306
307
impl MaxKey {
308
95.7k
    pub(crate) fn parse(self) -> Result<Bson> {
309
95.7k
        if self.value == 1 {
310
95.7k
            Ok(Bson::MaxKey)
311
        } else {
312
9
            Err(Error::invalid_value(
313
9
                Unexpected::Unsigned(self.value as u64),
314
9
                &"value of $maxKey should always be 1",
315
9
            ))
316
        }
317
95.7k
    }
318
}
319
320
#[derive(Deserialize)]
321
#[serde(deny_unknown_fields)]
322
pub(crate) struct DbPointer {
323
    #[serde(rename = "$dbPointer")]
324
    body: DbPointerBody,
325
}
326
327
#[derive(Serialize, Deserialize)]
328
#[serde(deny_unknown_fields)]
329
pub(crate) struct DbPointerBody {
330
    #[serde(rename = "$ref")]
331
    pub(crate) ref_ns: String,
332
333
    #[serde(rename = "$id")]
334
    pub(crate) id: ObjectId,
335
}
336
337
impl DbPointer {
338
0
    pub(crate) fn parse(self) -> Result<crate::DbPointer> {
339
0
        Ok(crate::DbPointer {
340
0
            namespace: self.body.ref_ns,
341
0
            id: self.body.id.parse()?,
342
        })
343
0
    }
344
}
345
346
#[derive(Deserialize)]
347
#[serde(deny_unknown_fields)]
348
pub(crate) struct Undefined {
349
    #[serde(rename = "$undefined")]
350
    pub(crate) value: bool,
351
}
352
353
impl Undefined {
354
67.5k
    pub(crate) fn parse(self) -> Result<Bson> {
355
67.5k
        if self.value {
356
67.5k
            Ok(Bson::Undefined)
357
        } else {
358
2
            Err(Error::invalid_value(
359
2
                Unexpected::Bool(false),
360
2
                &"$undefined should always be true",
361
2
            ))
362
        }
363
67.5k
    }
364
}
365
366
0
#[derive(Debug, Deserialize)]
Unexecuted instantiation: <<bson::extjson::models::BorrowedRegexBody as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_>::{closure#0}
Unexecuted instantiation: <<bson::extjson::models::BorrowedRegexBody as serde::de::Deserialize>::deserialize::__Visitor as serde::de::Visitor>::visit_seq::<_>::{closure#1}
367
pub(crate) struct BorrowedRegexBody<'a> {
368
    #[serde(borrow)]
369
    pub(crate) pattern: Cow<'a, str>,
370
371
    #[serde(borrow)]
372
    pub(crate) options: Cow<'a, str>,
373
}
374
375
0
#[derive(Debug, Deserialize)]
376
pub(crate) struct BorrowedBinaryBody<'a> {
377
    #[serde(borrow)]
378
    pub(crate) bytes: Cow<'a, [u8]>,
379
380
    #[serde(rename = "subType")]
381
    pub(crate) subtype: u8,
382
}
383
384
#[derive(Deserialize)]
385
pub(crate) struct BorrowedDbPointerBody<'a> {
386
    #[serde(rename = "$ref")]
387
    #[serde(borrow)]
388
    pub(crate) ns: CowStr<'a>,
389
390
    #[serde(rename = "$id")]
391
    pub(crate) id: oid::ObjectId,
392
}