Coverage Report

Created: 2026-10-17 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bson-rust/src/spec.rs
Line
Count
Source
1
// The MIT License (MIT)
2
3
// Copyright (c) 2015 Y. T. Chung <zonyitoo@gmail.com>
4
5
// Permission is hereby granted, free of charge, to any person obtaining a copy of
6
// this software and associated documentation files (the "Software"), to deal in
7
// the Software without restriction, including without limitation the rights to
8
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
// the Software, and to permit persons to whom the Software is furnished to do so,
10
// subject to the following conditions:
11
12
// The above copyright notice and this permission notice shall be included in all
13
// copies or substantial portions of the Software.
14
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22
//! Constants derived from the [BSON Specification Version 1.1](http://bsonspec.org/spec.html).
23
24
use std::{convert::From, fmt, hash::Hash};
25
26
impl fmt::LowerHex for BinarySubtype {
27
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28
0
        let value: u8 = (*self).into();
29
0
        fmt::LowerHex::fmt(&value, f)
30
0
    }
31
}
32
33
const ELEMENT_TYPE_FLOATING_POINT: u8 = 0x01;
34
const ELEMENT_TYPE_UTF8_STRING: u8 = 0x02;
35
const ELEMENT_TYPE_EMBEDDED_DOCUMENT: u8 = 0x03;
36
const ELEMENT_TYPE_ARRAY: u8 = 0x04;
37
const ELEMENT_TYPE_BINARY: u8 = 0x05;
38
const ELEMENT_TYPE_UNDEFINED: u8 = 0x06; // Deprecated
39
const ELEMENT_TYPE_OBJECT_ID: u8 = 0x07;
40
const ELEMENT_TYPE_BOOLEAN: u8 = 0x08;
41
const ELEMENT_TYPE_UTC_DATETIME: u8 = 0x09;
42
const ELEMENT_TYPE_NULL_VALUE: u8 = 0x0A;
43
const ELEMENT_TYPE_REGULAR_EXPRESSION: u8 = 0x0B;
44
const ELEMENT_TYPE_DBPOINTER: u8 = 0x0C; // Deprecated
45
const ELEMENT_TYPE_JAVASCRIPT_CODE: u8 = 0x0D;
46
const ELEMENT_TYPE_SYMBOL: u8 = 0x0E; // Deprecated
47
const ELEMENT_TYPE_JAVASCRIPT_CODE_WITH_SCOPE: u8 = 0x0F;
48
const ELEMENT_TYPE_32BIT_INTEGER: u8 = 0x10;
49
const ELEMENT_TYPE_TIMESTAMP: u8 = 0x11;
50
const ELEMENT_TYPE_64BIT_INTEGER: u8 = 0x12;
51
#[allow(unused)]
52
const ELEMENT_TYPE_128BIT_DECIMAL: u8 = 0x13;
53
const ELEMENT_TYPE_MINKEY: u8 = 0xFF;
54
const ELEMENT_TYPE_MAXKEY: u8 = 0x7F;
55
56
const BINARY_SUBTYPE_GENERIC: u8 = 0x00;
57
const BINARY_SUBTYPE_FUNCTION: u8 = 0x01;
58
const BINARY_SUBTYPE_BINARY_OLD: u8 = 0x02;
59
const BINARY_SUBTYPE_UUID_OLD: u8 = 0x03;
60
const BINARY_SUBTYPE_UUID: u8 = 0x04;
61
const BINARY_SUBTYPE_MD5: u8 = 0x05;
62
const BINARY_SUBTYPE_ENCRYPTED: u8 = 0x06;
63
const BINARY_SUBTYPE_COLUMN: u8 = 0x07;
64
const BINARY_SUBTYPE_SENSITIVE: u8 = 0x08;
65
const BINARY_SUBTYPE_VECTOR: u8 = 0x09;
66
const BINARY_SUBTYPE_USER_DEFINED: u8 = 0x80;
67
68
/// All available BSON element types.
69
///
70
/// Not all element types are representable by the [`Bson`](crate::Bson) type.
71
#[repr(u8)]
72
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
73
pub enum ElementType {
74
    /// 64-bit binary floating point.
75
    Double = ELEMENT_TYPE_FLOATING_POINT,
76
    /// UTF-8 string.
77
    String = ELEMENT_TYPE_UTF8_STRING,
78
    /// Embedded document.
79
    EmbeddedDocument = ELEMENT_TYPE_EMBEDDED_DOCUMENT,
80
    /// Array.
81
    Array = ELEMENT_TYPE_ARRAY,
82
    /// Binary data.
83
    Binary = ELEMENT_TYPE_BINARY,
84
    /// Deprecated.
85
    Undefined = ELEMENT_TYPE_UNDEFINED,
86
    /// [ObjectId](http://dochub.mongodb.org/core/objectids).
87
    ObjectId = ELEMENT_TYPE_OBJECT_ID,
88
    /// Boolean value.
89
    Boolean = ELEMENT_TYPE_BOOLEAN,
90
    /// UTC datetime.
91
    DateTime = ELEMENT_TYPE_UTC_DATETIME,
92
    /// Null value.
93
    Null = ELEMENT_TYPE_NULL_VALUE,
94
    /// Regular expression - The first cstring is the regex pattern, the second is the regex
95
    /// options string. Options are identified by characters, which must be stored in
96
    /// alphabetical order. Valid options are 'i' for case insensitive matching, 'm' for
97
    /// multiline matching, 'x' for verbose mode, 'l' to make \w, \W, etc. locale dependent,
98
    /// 's' for dotall mode ('.' matches everything), and 'u' to make \w, \W, etc. match
99
    /// unicode.
100
    RegularExpression = ELEMENT_TYPE_REGULAR_EXPRESSION,
101
    /// Deprecated.
102
    DbPointer = ELEMENT_TYPE_DBPOINTER,
103
    /// JavaScript code.
104
    JavaScriptCode = ELEMENT_TYPE_JAVASCRIPT_CODE,
105
    /// Deprecated.
106
    Symbol = ELEMENT_TYPE_SYMBOL,
107
    /// JavaScript code with scope.
108
    JavaScriptCodeWithScope = ELEMENT_TYPE_JAVASCRIPT_CODE_WITH_SCOPE,
109
    /// 32-bit integer.
110
    Int32 = ELEMENT_TYPE_32BIT_INTEGER,
111
    /// Timestamp.
112
    Timestamp = ELEMENT_TYPE_TIMESTAMP,
113
    /// 64-bit integer.
114
    Int64 = ELEMENT_TYPE_64BIT_INTEGER,
115
    /// [128-bit decimal floating point](https://github.com/mongodb/specifications/blob/master/source/bson-decimal128/decimal128.rst).
116
    Decimal128 = ELEMENT_TYPE_128BIT_DECIMAL,
117
    /// Maximum key.
118
    MaxKey = ELEMENT_TYPE_MAXKEY,
119
    /// Minimum key.
120
    MinKey = ELEMENT_TYPE_MINKEY,
121
}
122
123
impl ElementType {
124
    /// Attempt to convert from a `u8`.
125
    #[inline]
126
5.50M
    pub fn from(tag: u8) -> Option<ElementType> {
127
        use self::ElementType::*;
128
5.50M
        Some(match tag {
129
340k
            ELEMENT_TYPE_FLOATING_POINT => Self::Double,
130
74.1k
            ELEMENT_TYPE_UTF8_STRING => Self::String,
131
222k
            ELEMENT_TYPE_EMBEDDED_DOCUMENT => EmbeddedDocument,
132
83.3k
            ELEMENT_TYPE_ARRAY => Array,
133
411k
            ELEMENT_TYPE_BINARY => Binary,
134
521k
            ELEMENT_TYPE_UNDEFINED => Undefined,
135
97.0k
            ELEMENT_TYPE_OBJECT_ID => ObjectId,
136
380k
            ELEMENT_TYPE_BOOLEAN => Boolean,
137
274k
            ELEMENT_TYPE_UTC_DATETIME => Self::DateTime,
138
729k
            ELEMENT_TYPE_NULL_VALUE => Self::Null,
139
697k
            ELEMENT_TYPE_REGULAR_EXPRESSION => RegularExpression,
140
71.9k
            ELEMENT_TYPE_DBPOINTER => DbPointer,
141
76.8k
            ELEMENT_TYPE_JAVASCRIPT_CODE => JavaScriptCode,
142
57.7k
            ELEMENT_TYPE_SYMBOL => Symbol,
143
110k
            ELEMENT_TYPE_JAVASCRIPT_CODE_WITH_SCOPE => JavaScriptCodeWithScope,
144
86.4k
            ELEMENT_TYPE_32BIT_INTEGER => Int32,
145
57.6k
            ELEMENT_TYPE_TIMESTAMP => Timestamp,
146
56.3k
            ELEMENT_TYPE_64BIT_INTEGER => Int64,
147
56.8k
            ELEMENT_TYPE_128BIT_DECIMAL => Decimal128,
148
594k
            ELEMENT_TYPE_MAXKEY => MaxKey,
149
502k
            ELEMENT_TYPE_MINKEY => MinKey,
150
2.46k
            _ => return None,
151
        })
152
5.50M
    }
153
154
    #[cfg(feature = "serde")]
155
0
    pub(crate) fn name(&self) -> &'static str {
156
0
        match self {
157
0
            Self::Double => "double",
158
0
            Self::String => "string",
159
0
            Self::EmbeddedDocument => "document",
160
0
            Self::Array => "array",
161
0
            Self::Binary => "binary",
162
0
            Self::Undefined => "undefined",
163
0
            Self::ObjectId => "object ID",
164
0
            Self::Boolean => "boolean",
165
0
            Self::DateTime => "datetime",
166
0
            Self::Null => "null",
167
0
            Self::RegularExpression => "regular expression",
168
0
            Self::DbPointer => "DB pointer",
169
0
            Self::JavaScriptCode => "javascript code",
170
0
            Self::Symbol => "symbol",
171
0
            Self::JavaScriptCodeWithScope => "javascript code with scope",
172
0
            Self::Int32 => "int32",
173
0
            Self::Timestamp => "timestamp",
174
0
            Self::Int64 => "int64",
175
0
            Self::Decimal128 => "decimal128",
176
0
            Self::MaxKey => "max key",
177
0
            Self::MinKey => "min key",
178
        }
179
0
    }
180
}
181
182
/// The available binary subtypes, plus a user-defined slot.
183
#[derive(Copy, Clone, Debug, Eq)]
184
#[non_exhaustive]
185
#[allow(missing_docs)]
186
pub enum BinarySubtype {
187
    Generic,
188
    Function,
189
    BinaryOld,
190
    UuidOld,
191
    Uuid,
192
    Md5,
193
    Encrypted,
194
    Column,
195
    Sensitive,
196
    Vector,
197
    UserDefined(u8),
198
    Reserved(u8),
199
}
200
201
impl From<BinarySubtype> for u8 {
202
    #[inline]
203
211k
    fn from(t: BinarySubtype) -> u8 {
204
211k
        match t {
205
14.7k
            BinarySubtype::Generic => BINARY_SUBTYPE_GENERIC,
206
16.3k
            BinarySubtype::Function => BINARY_SUBTYPE_FUNCTION,
207
9.15k
            BinarySubtype::BinaryOld => BINARY_SUBTYPE_BINARY_OLD,
208
7.54k
            BinarySubtype::UuidOld => BINARY_SUBTYPE_UUID_OLD,
209
12.5k
            BinarySubtype::Uuid => BINARY_SUBTYPE_UUID,
210
26.0k
            BinarySubtype::Md5 => BINARY_SUBTYPE_MD5,
211
27.7k
            BinarySubtype::Encrypted => BINARY_SUBTYPE_ENCRYPTED,
212
9.42k
            BinarySubtype::Column => BINARY_SUBTYPE_COLUMN,
213
13.9k
            BinarySubtype::Sensitive => BINARY_SUBTYPE_SENSITIVE,
214
7.62k
            BinarySubtype::Vector => BINARY_SUBTYPE_VECTOR,
215
37.0k
            BinarySubtype::UserDefined(x) => x,
216
29.8k
            BinarySubtype::Reserved(x) => x,
217
        }
218
211k
    }
<u8 as core::convert::From<bson::spec::BinarySubtype>>::from
Line
Count
Source
203
104k
    fn from(t: BinarySubtype) -> u8 {
204
104k
        match t {
205
14.7k
            BinarySubtype::Generic => BINARY_SUBTYPE_GENERIC,
206
6.23k
            BinarySubtype::Function => BINARY_SUBTYPE_FUNCTION,
207
3.85k
            BinarySubtype::BinaryOld => BINARY_SUBTYPE_BINARY_OLD,
208
2.80k
            BinarySubtype::UuidOld => BINARY_SUBTYPE_UUID_OLD,
209
7.35k
            BinarySubtype::Uuid => BINARY_SUBTYPE_UUID,
210
11.0k
            BinarySubtype::Md5 => BINARY_SUBTYPE_MD5,
211
10.7k
            BinarySubtype::Encrypted => BINARY_SUBTYPE_ENCRYPTED,
212
3.88k
            BinarySubtype::Column => BINARY_SUBTYPE_COLUMN,
213
9.38k
            BinarySubtype::Sensitive => BINARY_SUBTYPE_SENSITIVE,
214
3.04k
            BinarySubtype::Vector => BINARY_SUBTYPE_VECTOR,
215
16.9k
            BinarySubtype::UserDefined(x) => x,
216
14.0k
            BinarySubtype::Reserved(x) => x,
217
        }
218
104k
    }
<u8 as core::convert::From<bson::spec::BinarySubtype>>::from
Line
Count
Source
203
56.7k
    fn from(t: BinarySubtype) -> u8 {
204
56.7k
        match t {
205
0
            BinarySubtype::Generic => BINARY_SUBTYPE_GENERIC,
206
5.89k
            BinarySubtype::Function => BINARY_SUBTYPE_FUNCTION,
207
1.87k
            BinarySubtype::BinaryOld => BINARY_SUBTYPE_BINARY_OLD,
208
866
            BinarySubtype::UuidOld => BINARY_SUBTYPE_UUID_OLD,
209
3.53k
            BinarySubtype::Uuid => BINARY_SUBTYPE_UUID,
210
13.1k
            BinarySubtype::Md5 => BINARY_SUBTYPE_MD5,
211
5.27k
            BinarySubtype::Encrypted => BINARY_SUBTYPE_ENCRYPTED,
212
4.13k
            BinarySubtype::Column => BINARY_SUBTYPE_COLUMN,
213
1.30k
            BinarySubtype::Sensitive => BINARY_SUBTYPE_SENSITIVE,
214
1.14k
            BinarySubtype::Vector => BINARY_SUBTYPE_VECTOR,
215
13.0k
            BinarySubtype::UserDefined(x) => x,
216
6.53k
            BinarySubtype::Reserved(x) => x,
217
        }
218
56.7k
    }
<u8 as core::convert::From<bson::spec::BinarySubtype>>::from
Line
Count
Source
203
51.1k
    fn from(t: BinarySubtype) -> u8 {
204
51.1k
        match t {
205
0
            BinarySubtype::Generic => BINARY_SUBTYPE_GENERIC,
206
4.17k
            BinarySubtype::Function => BINARY_SUBTYPE_FUNCTION,
207
3.42k
            BinarySubtype::BinaryOld => BINARY_SUBTYPE_BINARY_OLD,
208
3.87k
            BinarySubtype::UuidOld => BINARY_SUBTYPE_UUID_OLD,
209
1.62k
            BinarySubtype::Uuid => BINARY_SUBTYPE_UUID,
210
1.84k
            BinarySubtype::Md5 => BINARY_SUBTYPE_MD5,
211
11.7k
            BinarySubtype::Encrypted => BINARY_SUBTYPE_ENCRYPTED,
212
1.40k
            BinarySubtype::Column => BINARY_SUBTYPE_COLUMN,
213
3.26k
            BinarySubtype::Sensitive => BINARY_SUBTYPE_SENSITIVE,
214
3.44k
            BinarySubtype::Vector => BINARY_SUBTYPE_VECTOR,
215
7.05k
            BinarySubtype::UserDefined(x) => x,
216
9.26k
            BinarySubtype::Reserved(x) => x,
217
        }
218
51.1k
    }
219
}
220
221
impl From<u8> for BinarySubtype {
222
    #[inline]
223
527k
    fn from(t: u8) -> BinarySubtype {
224
117k
        match t {
225
115k
            BINARY_SUBTYPE_GENERIC => BinarySubtype::Generic,
226
30.1k
            BINARY_SUBTYPE_FUNCTION => BinarySubtype::Function,
227
60.7k
            BINARY_SUBTYPE_BINARY_OLD => BinarySubtype::BinaryOld,
228
16.3k
            BINARY_SUBTYPE_UUID_OLD => BinarySubtype::UuidOld,
229
23.7k
            BINARY_SUBTYPE_UUID => BinarySubtype::Uuid,
230
57.6k
            BINARY_SUBTYPE_MD5 => BinarySubtype::Md5,
231
51.0k
            BINARY_SUBTYPE_ENCRYPTED => BinarySubtype::Encrypted,
232
15.5k
            BINARY_SUBTYPE_COLUMN => BinarySubtype::Column,
233
23.8k
            BINARY_SUBTYPE_SENSITIVE => BinarySubtype::Sensitive,
234
15.2k
            BINARY_SUBTYPE_VECTOR => BinarySubtype::Vector,
235
117k
            _ if t < BINARY_SUBTYPE_USER_DEFINED => BinarySubtype::Reserved(t),
236
59.9k
            _ => BinarySubtype::UserDefined(t),
237
        }
238
527k
    }
239
}
240
241
// Manual implemntation to ensure that Generic == UserDefined(0x00) == Reserved(0x00)
242
impl PartialEq for BinarySubtype {
243
17.0k
    fn eq(&self, other: &BinarySubtype) -> bool {
244
17.0k
        u8::from(*self) == u8::from(*other)
245
17.0k
    }
246
}
247
248
impl Hash for BinarySubtype {
249
0
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
250
0
        u8::from(*self).hash(state);
251
0
    }
252
}
253
254
impl Ord for BinarySubtype {
255
0
    fn cmp(&self, other: &BinarySubtype) -> std::cmp::Ordering {
256
0
        u8::from(*self).cmp(&u8::from(*other))
257
0
    }
258
}
259
260
impl PartialOrd for BinarySubtype {
261
0
    fn partial_cmp(&self, other: &BinarySubtype) -> Option<std::cmp::Ordering> {
262
0
        Some(self.cmp(other))
263
0
    }
264
}