Coverage Report

Created: 2025-12-31 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/OpenSK/libraries/cbor/src/values.rs
Line
Count
Source
1
// Copyright 2019 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
//! Types for expressing CBOR values.
16
17
use alloc::boxed::Box;
18
use alloc::string::{String, ToString};
19
use alloc::vec::Vec;
20
use core::cmp::Ordering;
21
22
/// The CBOR data structure.
23
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
24
pub struct Value(pub(crate) ValueImpl);
25
26
/// Possible CBOR values.
27
#[derive(Clone, Debug)]
28
pub(crate) enum ValueImpl {
29
    /// Unsigned integer value (uint).
30
    Unsigned(u64),
31
    /// Signed integer value (nint). Only 63 bits of information are used here.
32
    Negative(i64),
33
    /// Byte string (bstr).
34
    ByteString(Vec<u8>),
35
    /// Text string (tstr).
36
    TextString(String),
37
    /// Array/tuple of values.
38
    Array(Vec<Value>),
39
    /// Map of key-value pairs.
40
    Map(Vec<(Value, Value)>),
41
    /// Tagged value.
42
    Tag(u64, Box<Value>),
43
    /// Simple value.
44
    Simple(SimpleValue),
45
}
46
47
/// Specific simple CBOR values.
48
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
49
pub(crate) enum SimpleValue {
50
    FalseValue = 20,
51
    TrueValue = 21,
52
    NullValue = 22,
53
    Undefined = 23,
54
}
55
56
/// Constant values required for CBOR encoding.
57
pub struct Constants {}
58
59
impl Constants {
60
    /// Number of bits used to shift left the major type of a CBOR type byte.
61
    pub const MAJOR_TYPE_BIT_SHIFT: u8 = 5;
62
    /// Mask to retrieve the additional information held in a CBOR type bytes,
63
    /// ignoring the major type.
64
    pub const ADDITIONAL_INFORMATION_MASK: u8 = 0x1F;
65
    /// Additional information value that indicates the largest inline value.
66
    pub const ADDITIONAL_INFORMATION_MAX_INT: u8 = 23;
67
    /// Additional information value indicating that a 1-byte length follows.
68
    pub const ADDITIONAL_INFORMATION_1_BYTE: u8 = 24;
69
    /// Additional information value indicating that a 2-byte length follows.
70
    pub const ADDITIONAL_INFORMATION_2_BYTES: u8 = 25;
71
    /// Additional information value indicating that a 4-byte length follows.
72
    pub const ADDITIONAL_INFORMATION_4_BYTES: u8 = 26;
73
    /// Additional information value indicating that an 8-byte length follows.
74
    pub const ADDITIONAL_INFORMATION_8_BYTES: u8 = 27;
75
}
76
77
impl Value {
78
    /// Creates a CBOR unsigned value.
79
9.61M
    pub fn unsigned(int: u64) -> Value {
80
9.61M
        Value(ValueImpl::Unsigned(int))
81
9.61M
    }
82
83
    /// Create an appropriate CBOR integer value (uint/nint).
84
    /// For simplicity, this only takes i64. Construct directly for the last bit.
85
166k
    pub fn integer(int: i64) -> Value {
86
166k
        if int >= 0 {
87
143k
            Value(ValueImpl::Unsigned(int as u64))
88
        } else {
89
22.5k
            Value(ValueImpl::Negative(int))
90
        }
91
166k
    }
92
93
    /// Creates a CBOR byte string value.
94
963k
    pub fn byte_string(bytes: Vec<u8>) -> Value {
95
963k
        Value(ValueImpl::ByteString(bytes))
96
963k
    }
97
98
    /// Creates a CBOR text string value.
99
174k
    pub fn text_string(text: String) -> Value {
100
174k
        Value(ValueImpl::TextString(text))
101
174k
    }
102
103
    /// Create a CBOR array value.
104
1.87M
    pub fn array(a: Vec<Value>) -> Value {
105
1.87M
        Value(ValueImpl::Array(a))
106
1.87M
    }
107
108
    /// Create a CBOR map value.
109
    ///
110
    /// Keys do not have to be sorted.
111
    ///
112
    /// # Panics
113
    ///
114
    /// You may not call this function with identical keys in its argument.
115
459k
    pub fn map(mut m: Vec<(Value, Value)>) -> Value {
116
459k
        m.sort_by(|a, b| a.0.cmp(&b.0));
117
459k
        let map_len = m.len();
118
459k
        m.dedup_by(|a, b| a.0.eq(&b.0));
119
459k
        if map_len != m.len() {
120
0
            panic!();
121
459k
        }
122
459k
        Value(ValueImpl::Map(m))
123
459k
    }
124
125
    /// Create a CBOR tagged value.
126
1.51M
    pub fn tag(int: u64, value: Value) -> Value {
127
1.51M
        Value(ValueImpl::Tag(int, Box::new(value)))
128
1.51M
    }
129
130
    /// Create a CBOR boolean simple value.
131
1.32k
    pub fn bool_value(b: bool) -> Value {
132
1.32k
        if b {
133
1.00k
            Value(ValueImpl::Simple(SimpleValue::TrueValue))
134
        } else {
135
327
            Value(ValueImpl::Simple(SimpleValue::FalseValue))
136
        }
137
1.32k
    }
138
139
    /// Creates a null value.
140
0
    pub fn null_value() -> Value {
141
0
        Value(ValueImpl::Simple(SimpleValue::NullValue))
142
0
    }
143
144
    /// Creates an undefined value.
145
0
    pub fn undefined() -> Value {
146
0
        Value(ValueImpl::Simple(SimpleValue::Undefined))
147
0
    }
148
149
10.4k
    pub fn extract_unsigned(self) -> Option<u64> {
150
10.4k
        match self {
151
10.2k
            Value(ValueImpl::Unsigned(unsigned)) => Some(unsigned),
152
137
            _ => None,
153
        }
154
10.4k
    }
155
156
3.77k
    pub fn extract_integer(self) -> Option<i64> {
157
3.77k
        match self {
158
846
            Value(ValueImpl::Unsigned(unsigned)) => {
159
846
                if unsigned <= i64::MAX as u64 {
160
578
                    Some(unsigned as i64)
161
                } else {
162
268
                    None
163
                }
164
            }
165
2.89k
            Value(ValueImpl::Negative(signed)) => Some(signed),
166
29
            _ => None,
167
        }
168
3.77k
    }
169
170
18.1k
    pub fn extract_byte_string(self) -> Option<Vec<u8>> {
171
18.1k
        match self {
172
17.9k
            Value(ValueImpl::ByteString(byte_string)) => Some(byte_string),
173
177
            _ => None,
174
        }
175
18.1k
    }
176
177
19.2k
    pub fn extract_text_string(self) -> Option<String> {
178
19.2k
        match self {
179
19.0k
            Value(ValueImpl::TextString(text_string)) => Some(text_string),
180
144
            _ => None,
181
        }
182
19.2k
    }
183
184
6.75k
    pub fn extract_array(self) -> Option<Vec<Value>> {
185
6.75k
        match self {
186
6.73k
            Value(ValueImpl::Array(array)) => Some(array),
187
27
            _ => None,
188
        }
189
6.75k
    }
190
191
34.4k
    pub fn extract_map(self) -> Option<Vec<(Value, Value)>> {
192
34.4k
        match self {
193
33.7k
            Value(ValueImpl::Map(map)) => Some(map),
194
773
            _ => None,
195
        }
196
34.4k
    }
197
198
0
    pub fn extract_tag(self) -> Option<(u64, Value)> {
199
0
        match self {
200
0
            Value(ValueImpl::Tag(tag, value)) => Some((tag, *value)),
201
0
            _ => None,
202
        }
203
0
    }
204
205
825
    pub fn extract_bool(self) -> Option<bool> {
206
694
        match self {
207
33
            Value(ValueImpl::Simple(SimpleValue::FalseValue)) => Some(false),
208
653
            Value(ValueImpl::Simple(SimpleValue::TrueValue)) => Some(true),
209
139
            _ => None,
210
        }
211
825
    }
212
213
0
    pub fn extract_null(self) -> Option<()> {
214
0
        match self {
215
0
            Value(ValueImpl::Simple(SimpleValue::NullValue)) => Some(()),
216
0
            _ => None,
217
        }
218
0
    }
219
220
0
    pub fn extract_undefined(self) -> Option<()> {
221
0
        match self {
222
0
            Value(ValueImpl::Simple(SimpleValue::Undefined)) => Some(()),
223
0
            _ => None,
224
        }
225
0
    }
226
}
227
228
impl ValueImpl {
229
    /// Return the major type for the [`ValueImpl`].
230
9.12M
    pub fn type_label(&self) -> u8 {
231
        // TODO use enum discriminant instead when stable
232
        // https://github.com/rust-lang/rust/issues/60553
233
9.12M
        match self {
234
1.78M
            ValueImpl::Unsigned(_) => 0,
235
2.23M
            ValueImpl::Negative(_) => 1,
236
1.60M
            ValueImpl::ByteString(_) => 2,
237
218k
            ValueImpl::TextString(_) => 3,
238
540k
            ValueImpl::Array(_) => 4,
239
428k
            ValueImpl::Map(_) => 5,
240
2.26M
            ValueImpl::Tag(_, _) => 6,
241
53.3k
            ValueImpl::Simple(_) => 7,
242
        }
243
9.12M
    }
244
}
245
246
impl Ord for ValueImpl {
247
1.28M
    fn cmp(&self, other: &ValueImpl) -> Ordering {
248
        use super::values::ValueImpl::{
249
            Array, ByteString, Map, Negative, Simple, Tag, TextString, Unsigned,
250
        };
251
1.28M
        let self_type_value = self.type_label();
252
1.28M
        let other_type_value = other.type_label();
253
1.28M
        if self_type_value != other_type_value {
254
865k
            return self_type_value.cmp(&other_type_value);
255
421k
        }
256
421k
        match (self, other) {
257
218k
            (Unsigned(u1), Unsigned(u2)) => u1.cmp(u2),
258
49.4k
            (Negative(n1), Negative(n2)) => n1.cmp(n2).reverse(),
259
36.6k
            (ByteString(b1), ByteString(b2)) => b1.len().cmp(&b2.len()).then(b1.cmp(b2)),
260
67.6k
            (TextString(t1), TextString(t2)) => t1.len().cmp(&t2.len()).then(t1.cmp(t2)),
261
6.66k
            (Array(a1), Array(a2)) if a1.len() != a2.len() => a1.len().cmp(&a2.len()),
262
4.40k
            (Array(a1), Array(a2)) => {
263
                // Arrays of same length.
264
4.40k
                let mut ordering = Ordering::Equal;
265
7.47k
                for (e1, e2) in a1.iter().zip(a2.iter()) {
266
7.47k
                    ordering = e1.cmp(e2);
267
7.47k
                    if !matches!(ordering, Ordering::Equal) {
268
2.10k
                        break;
269
5.36k
                    }
270
                }
271
4.40k
                ordering
272
            }
273
11.4k
            (Map(m1), Map(m2)) if m1.len() != m2.len() => m1.len().cmp(&m2.len()),
274
8.22k
            (Map(m1), Map(m2)) => {
275
                // Maps of same length.
276
8.22k
                let mut ordering = Ordering::Equal;
277
9.67k
                for ((k1, v1), (k2, v2)) in m1.iter().zip(m2.iter()) {
278
9.67k
                    ordering = k1.cmp(k2).then_with(|| v1.cmp(v2));
279
9.67k
                    if !matches!(ordering, Ordering::Equal) {
280
4.42k
                        break;
281
5.24k
                    }
282
                }
283
8.22k
                ordering
284
            }
285
25.3k
            (Tag(t1, v1), Tag(t2, v2)) => t1.cmp(t2).then(v1.cmp(v2)),
286
5.91k
            (Simple(s1), Simple(s2)) => s1.cmp(s2),
287
            (_, _) => {
288
                // The case of different major types is caught above.
289
0
                unreachable!();
290
            }
291
        }
292
1.28M
    }
293
}
294
295
impl PartialOrd for ValueImpl {
296
356k
    fn partial_cmp(&self, other: &ValueImpl) -> Option<Ordering> {
297
356k
        Some(self.cmp(other))
298
356k
    }
299
}
300
301
impl Eq for ValueImpl {}
302
303
impl PartialEq for ValueImpl {
304
384k
    fn eq(&self, other: &ValueImpl) -> bool {
305
384k
        self.cmp(other) == Ordering::Equal
306
384k
    }
307
}
308
309
impl SimpleValue {
310
    /// Create a simple value from its encoded value.
311
49.2k
    pub fn from_integer(int: u64) -> Option<SimpleValue> {
312
49.2k
        match int {
313
4.18k
            20 => Some(SimpleValue::FalseValue),
314
5.48k
            21 => Some(SimpleValue::TrueValue),
315
12.9k
            22 => Some(SimpleValue::NullValue),
316
26.5k
            23 => Some(SimpleValue::Undefined),
317
95
            _ => None,
318
        }
319
49.2k
    }
320
}
321
322
impl From<u64> for Value {
323
13.7k
    fn from(u: u64) -> Self {
324
13.7k
        Value::unsigned(u)
325
13.7k
    }
326
}
327
328
impl From<u32> for Value {
329
0
    fn from(u: u32) -> Self {
330
0
        Value::unsigned(u as u64)
331
0
    }
332
}
333
334
impl From<u16> for Value {
335
0
    fn from(u: u16) -> Self {
336
0
        Value::unsigned(u as u64)
337
0
    }
338
}
339
340
impl From<u8> for Value {
341
0
    fn from(u: u8) -> Self {
342
0
        Value::unsigned(u as u64)
343
0
    }
344
}
345
346
impl From<i64> for Value {
347
14.0k
    fn from(i: i64) -> Self {
348
14.0k
        Value::integer(i)
349
14.0k
    }
350
}
351
352
impl From<i32> for Value {
353
148k
    fn from(i: i32) -> Self {
354
148k
        Value::integer(i as i64)
355
148k
    }
356
}
357
358
impl From<i16> for Value {
359
0
    fn from(i: i16) -> Self {
360
0
        Value::integer(i as i64)
361
0
    }
362
}
363
364
impl From<i8> for Value {
365
0
    fn from(i: i8) -> Self {
366
0
        Value::integer(i as i64)
367
0
    }
368
}
369
370
impl From<Vec<u8>> for Value {
371
9.47k
    fn from(bytes: Vec<u8>) -> Self {
372
9.47k
        Value(ValueImpl::ByteString(bytes))
373
9.47k
    }
374
}
375
376
impl From<&[u8]> for Value {
377
6.48k
    fn from(bytes: &[u8]) -> Self {
378
6.48k
        Value(ValueImpl::ByteString(bytes.to_vec()))
379
6.48k
    }
380
}
381
382
impl From<&[u8; 0]> for Value {
383
0
    fn from(bytes: &[u8; 0]) -> Self {
384
0
        Value(ValueImpl::ByteString(bytes.to_vec()))
385
0
    }
386
}
387
388
impl From<String> for Value {
389
4.90k
    fn from(text: String) -> Self {
390
4.90k
        Value(ValueImpl::TextString(text))
391
4.90k
    }
392
}
393
394
impl From<&str> for Value {
395
58.9k
    fn from(text: &str) -> Self {
396
58.9k
        Value(ValueImpl::TextString(text.to_string()))
397
58.9k
    }
398
}
399
400
impl From<Vec<Value>> for Value {
401
0
    fn from(array: Vec<Value>) -> Self {
402
0
        Value(ValueImpl::Array(array))
403
0
    }
404
}
405
406
impl From<Vec<(Value, Value)>> for Value {
407
0
    fn from(map: Vec<(Value, Value)>) -> Self {
408
0
        Value::map(map)
409
0
    }
410
}
411
412
impl From<bool> for Value {
413
701
    fn from(b: bool) -> Self {
414
701
        Value::bool_value(b)
415
701
    }
416
}
417
418
/// Trait that indicates that a type can be converted to a CBOR [`Value`].
419
pub trait IntoCborValue {
420
    /// Convert `self` into a CBOR [`Value`], consuming it along the way.
421
    fn into_cbor_value(self) -> Value;
422
}
423
424
impl<T> IntoCborValue for T
425
where
426
    Value: From<T>,
427
{
428
7.91M
    fn into_cbor_value(self) -> Value {
429
7.91M
        Value::from(self)
430
7.91M
    }
<opensk::api::key_store::CredentialSourceField as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
4.61k
    fn into_cbor_value(self) -> Value {
429
4.61k
        Value::from(self)
430
4.61k
    }
<alloc::string::String as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
1.41k
    fn into_cbor_value(self) -> Value {
429
1.41k
        Value::from(self)
430
1.41k
    }
Unexecuted instantiation: <alloc::vec::Vec<u8> as sk_cbor::values::IntoCborValue>::into_cbor_value
<opensk::ctap::data_formats::AuthenticatorTransport as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
57
    fn into_cbor_value(self) -> Value {
429
57
        Value::from(self)
430
57
    }
<opensk::ctap::data_formats::PublicKeyCredentialParameter as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
57
    fn into_cbor_value(self) -> Value {
429
57
        Value::from(self)
430
57
    }
<opensk::ctap::data_formats::PublicKeyCredentialSourceField as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
7.31k
    fn into_cbor_value(self) -> Value {
429
7.31k
        Value::from(self)
430
7.31k
    }
<&str as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
58.8k
    fn into_cbor_value(self) -> Value {
429
58.8k
        Value::from(self)
430
58.8k
    }
<i32 as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
148k
    fn into_cbor_value(self) -> Value {
429
148k
        Value::from(self)
430
148k
    }
<u64 as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
114
    fn into_cbor_value(self) -> Value {
429
114
        Value::from(self)
430
114
    }
<sk_cbor::values::Value as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
7.69M
    fn into_cbor_value(self) -> Value {
429
7.69M
        Value::from(self)
430
7.69M
    }
431
}
432
433
/// Trait that indicates that a type can be converted to a CBOR [`Option<Value>`].
434
pub trait IntoCborValueOption {
435
    /// Convert `self` into a CBOR [`Option<Value>`], consuming it along the way.
436
    fn into_cbor_value_option(self) -> Option<Value>;
437
}
438
439
impl<T> IntoCborValueOption for T
440
where
441
    Value: From<T>,
442
{
443
29.5k
    fn into_cbor_value_option(self) -> Option<Value> {
444
29.5k
        Some(Value::from(self))
445
29.5k
    }
<alloc::string::String as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
1.12k
    fn into_cbor_value_option(self) -> Option<Value> {
444
1.12k
        Some(Value::from(self))
445
1.12k
    }
<alloc::vec::Vec<u8> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
2.51k
    fn into_cbor_value_option(self) -> Option<Value> {
444
2.51k
        Some(Value::from(self))
445
2.51k
    }
<opensk::ctap::data_formats::SignatureAlgorithm as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
57
    fn into_cbor_value_option(self) -> Option<Value> {
444
57
        Some(Value::from(self))
445
57
    }
<opensk::ctap::data_formats::PublicKeyCredentialType as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
57
    fn into_cbor_value_option(self) -> Option<Value> {
444
57
        Some(Value::from(self))
445
57
    }
<opensk::ctap::data_formats::PackedAttestationStatement as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
1.12k
    fn into_cbor_value_option(self) -> Option<Value> {
444
1.12k
        Some(Value::from(self))
445
1.12k
    }
<sk_cbor::values::Value as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
3.37k
    fn into_cbor_value_option(self) -> Option<Value> {
444
3.37k
        Some(Value::from(self))
445
3.37k
    }
<&[u8] as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
6.48k
    fn into_cbor_value_option(self) -> Option<Value> {
444
6.48k
        Some(Value::from(self))
445
6.48k
    }
<i64 as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
13.7k
    fn into_cbor_value_option(self) -> Option<Value> {
444
13.7k
        Some(Value::from(self))
445
13.7k
    }
<u64 as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
1.13k
    fn into_cbor_value_option(self) -> Option<Value> {
444
1.13k
        Some(Value::from(self))
445
1.13k
    }
446
}
447
448
impl<T> IntoCborValueOption for Option<T>
449
where
450
    Value: From<T>,
451
{
452
32.2k
    fn into_cbor_value_option(self) -> Option<Value> {
453
32.2k
        self.map(Value::from)
454
32.2k
    }
<core::option::Option<alloc::vec::Vec<u8>> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
14.3k
    fn into_cbor_value_option(self) -> Option<Value> {
453
14.3k
        self.map(Value::from)
454
14.3k
    }
<core::option::Option<sk_cbor::values::Value> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
2.73k
    fn into_cbor_value_option(self) -> Option<Value> {
453
2.73k
        self.map(Value::from)
454
2.73k
    }
<core::option::Option<alloc::string::String> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
4.38k
    fn into_cbor_value_option(self) -> Option<Value> {
453
4.38k
        self.map(Value::from)
454
4.38k
    }
<core::option::Option<opensk::ctap::data_formats::CredentialProtectionPolicy> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
3.76k
    fn into_cbor_value_option(self) -> Option<Value> {
453
3.76k
        self.map(Value::from)
454
3.76k
    }
Unexecuted instantiation: <core::option::Option<opensk::ctap::data_formats::PublicKeyCredentialRpEntity> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
<core::option::Option<opensk::ctap::data_formats::PublicKeyCredentialDescriptor> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
51
    fn into_cbor_value_option(self) -> Option<Value> {
453
51
        self.map(Value::from)
454
51
    }
<core::option::Option<opensk::ctap::data_formats::PublicKeyCredentialUserEntity> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
51
    fn into_cbor_value_option(self) -> Option<Value> {
453
51
        self.map(Value::from)
454
51
    }
<core::option::Option<bool> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
3.35k
    fn into_cbor_value_option(self) -> Option<Value> {
453
3.35k
        self.map(Value::from)
454
3.35k
    }
<core::option::Option<u64> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
3.56k
    fn into_cbor_value_option(self) -> Option<Value> {
453
3.56k
        self.map(Value::from)
454
3.56k
    }
455
}
456
457
#[cfg(test)]
458
mod test {
459
    use super::*;
460
    use crate::{
461
        cbor_array, cbor_bool, cbor_bytes, cbor_bytes_lit, cbor_int, cbor_map, cbor_null,
462
        cbor_tagged, cbor_text, cbor_undefined, cbor_unsigned,
463
    };
464
    use alloc::vec;
465
466
    #[test]
467
    #[should_panic]
468
    fn test_duplicate_map_key() {
469
        let _map = cbor_map! {
470
            0 => "a",
471
            -1 => "c",
472
            b"a" => "e",
473
            "c" => "g",
474
            0 => "b",
475
        };
476
    }
477
478
    #[test]
479
    fn test_extract_unsigned() {
480
        assert_eq!(cbor_int!(1).extract_unsigned(), Some(1));
481
        assert_eq!(cbor_int!(-1).extract_unsigned(), None);
482
        assert_eq!(cbor_bytes!(vec![]).extract_unsigned(), None);
483
        assert_eq!(cbor_text!("").extract_unsigned(), None);
484
        assert_eq!(cbor_array![].extract_unsigned(), None);
485
        assert_eq!(cbor_map! {}.extract_unsigned(), None);
486
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_unsigned(), None);
487
        assert_eq!(cbor_bool!(false).extract_unsigned(), None);
488
    }
489
490
    #[test]
491
    fn test_extract_unsigned_limits() {
492
        assert_eq!(
493
            cbor_unsigned!(core::u64::MAX).extract_unsigned(),
494
            Some(core::u64::MAX)
495
        );
496
        assert_eq!(
497
            cbor_unsigned!((core::i64::MAX as u64) + 1).extract_unsigned(),
498
            Some((core::i64::MAX as u64) + 1)
499
        );
500
        assert_eq!(
501
            cbor_int!(core::i64::MAX).extract_unsigned(),
502
            Some(core::i64::MAX as u64)
503
        );
504
        assert_eq!(cbor_int!(123).extract_unsigned(), Some(123));
505
        assert_eq!(cbor_int!(0).extract_unsigned(), Some(0));
506
        assert_eq!(cbor_int!(-123).extract_unsigned(), None);
507
        assert_eq!(cbor_int!(core::i64::MIN).extract_unsigned(), None);
508
    }
509
510
    #[test]
511
    fn test_extract_integer() {
512
        assert_eq!(cbor_int!(1).extract_integer(), Some(1));
513
        assert_eq!(cbor_int!(-1).extract_integer(), Some(-1));
514
        assert_eq!(cbor_bytes!(vec![]).extract_integer(), None);
515
        assert_eq!(cbor_text!("").extract_integer(), None);
516
        assert_eq!(cbor_array![].extract_integer(), None);
517
        assert_eq!(cbor_map! {}.extract_integer(), None);
518
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_integer(), None);
519
        assert_eq!(cbor_bool!(false).extract_integer(), None);
520
    }
521
522
    #[test]
523
    fn test_extract_integer_limits() {
524
        assert_eq!(cbor_unsigned!(core::u64::MAX).extract_integer(), None);
525
        assert_eq!(
526
            cbor_unsigned!((core::i64::MAX as u64) + 1).extract_integer(),
527
            None
528
        );
529
        assert_eq!(
530
            cbor_int!(core::i64::MAX).extract_integer(),
531
            Some(core::i64::MAX)
532
        );
533
        assert_eq!(cbor_int!(123).extract_integer(), Some(123));
534
        assert_eq!(cbor_int!(0).extract_integer(), Some(0));
535
        assert_eq!(cbor_int!(-123).extract_integer(), Some(-123));
536
        assert_eq!(
537
            cbor_int!(core::i64::MIN).extract_integer(),
538
            Some(core::i64::MIN)
539
        );
540
    }
541
542
    #[test]
543
    fn test_extract_byte_string() {
544
        assert_eq!(cbor_int!(1).extract_byte_string(), None);
545
        assert_eq!(cbor_int!(-1).extract_byte_string(), None);
546
        assert_eq!(cbor_bytes!(vec![]).extract_byte_string(), Some(Vec::new()));
547
        assert_eq!(
548
            cbor_bytes_lit!(b"bar").extract_byte_string(),
549
            Some(b"bar".to_vec())
550
        );
551
        assert_eq!(cbor_text!("").extract_byte_string(), None);
552
        assert_eq!(cbor_array![].extract_byte_string(), None);
553
        assert_eq!(cbor_map! {}.extract_byte_string(), None);
554
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_byte_string(), None);
555
        assert_eq!(cbor_bool!(false).extract_byte_string(), None);
556
    }
557
558
    #[test]
559
    fn test_extract_text_string() {
560
        assert_eq!(cbor_int!(1).extract_text_string(), None);
561
        assert_eq!(cbor_int!(-1).extract_text_string(), None);
562
        assert_eq!(cbor_bytes!(vec![]).extract_text_string(), None);
563
        assert_eq!(cbor_text!("").extract_text_string(), Some(String::new()));
564
        assert_eq!(cbor_text!("s").extract_text_string(), Some("s".to_string()));
565
        assert_eq!(cbor_array![].extract_text_string(), None);
566
        assert_eq!(cbor_map! {}.extract_text_string(), None);
567
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_text_string(), None);
568
        assert_eq!(cbor_bool!(false).extract_text_string(), None);
569
    }
570
571
    #[test]
572
    fn test_extract_array() {
573
        assert_eq!(cbor_int!(1).extract_array(), None);
574
        assert_eq!(cbor_int!(-1).extract_array(), None);
575
        assert_eq!(cbor_bytes!(vec![]).extract_array(), None);
576
        assert_eq!(cbor_text!("").extract_array(), None);
577
        assert_eq!(cbor_array![].extract_array(), Some(Vec::new()));
578
        assert_eq!(
579
            cbor_array![cbor_int!(1)].extract_array(),
580
            Some(vec![cbor_int!(1)])
581
        );
582
        assert_eq!(cbor_map! {}.extract_array(), None);
583
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_array(), None);
584
        assert_eq!(cbor_bool!(false).extract_array(), None);
585
    }
586
587
    #[test]
588
    fn test_extract_map() {
589
        assert_eq!(cbor_int!(1).extract_map(), None);
590
        assert_eq!(cbor_int!(-1).extract_map(), None);
591
        assert_eq!(cbor_bytes!(vec![]).extract_map(), None);
592
        assert_eq!(cbor_text!("").extract_map(), None);
593
        assert_eq!(cbor_array![].extract_map(), None);
594
        assert_eq!(cbor_map! {}.extract_map(), Some(Vec::new()));
595
        assert_eq!(
596
            cbor_map! {0 => 1}.extract_map(),
597
            Some(vec![(cbor_int!(0), cbor_int!(1))])
598
        );
599
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_map(), None);
600
        assert_eq!(cbor_bool!(false).extract_map(), None);
601
    }
602
603
    #[test]
604
    fn test_extract_tag() {
605
        assert_eq!(cbor_int!(1).extract_tag(), None);
606
        assert_eq!(cbor_int!(-1).extract_tag(), None);
607
        assert_eq!(cbor_bytes!(vec![]).extract_tag(), None);
608
        assert_eq!(cbor_text!("").extract_tag(), None);
609
        assert_eq!(cbor_array![].extract_tag(), None);
610
        assert_eq!(cbor_map! {}.extract_tag(), None);
611
        assert_eq!(
612
            cbor_tagged!(1, cbor_text!("s")).extract_tag(),
613
            Some((1, cbor_text!("s")))
614
        );
615
        assert_eq!(cbor_bool!(false).extract_tag(), None);
616
    }
617
618
    #[test]
619
    fn test_extract_bool() {
620
        assert_eq!(cbor_int!(1).extract_bool(), None);
621
        assert_eq!(cbor_int!(-1).extract_bool(), None);
622
        assert_eq!(cbor_bytes!(vec![]).extract_bool(), None);
623
        assert_eq!(cbor_text!("").extract_bool(), None);
624
        assert_eq!(cbor_array![].extract_bool(), None);
625
        assert_eq!(cbor_map! {}.extract_bool(), None);
626
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_bool(), None);
627
        assert_eq!(cbor_bool!(false).extract_bool(), Some(false));
628
        assert_eq!(cbor_bool!(true).extract_bool(), Some(true));
629
        assert_eq!(cbor_null!().extract_bool(), None);
630
        assert_eq!(cbor_undefined!().extract_bool(), None);
631
    }
632
633
    #[test]
634
    fn test_extract_null() {
635
        assert_eq!(cbor_int!(1).extract_null(), None);
636
        assert_eq!(cbor_int!(-1).extract_null(), None);
637
        assert_eq!(cbor_bytes!(vec![]).extract_null(), None);
638
        assert_eq!(cbor_text!("").extract_null(), None);
639
        assert_eq!(cbor_array![].extract_null(), None);
640
        assert_eq!(cbor_map! {}.extract_null(), None);
641
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_null(), None);
642
        assert_eq!(cbor_bool!(false).extract_null(), None);
643
        assert_eq!(cbor_bool!(true).extract_null(), None);
644
        assert_eq!(cbor_null!().extract_null(), Some(()));
645
        assert_eq!(cbor_undefined!().extract_null(), None);
646
    }
647
648
    #[test]
649
    fn test_extract_undefined() {
650
        assert_eq!(cbor_int!(1).extract_undefined(), None);
651
        assert_eq!(cbor_int!(-1).extract_undefined(), None);
652
        assert_eq!(cbor_bytes!(vec![]).extract_undefined(), None);
653
        assert_eq!(cbor_text!("").extract_undefined(), None);
654
        assert_eq!(cbor_array![].extract_undefined(), None);
655
        assert_eq!(cbor_map! {}.extract_undefined(), None);
656
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_undefined(), None);
657
        assert_eq!(cbor_bool!(false).extract_undefined(), None);
658
        assert_eq!(cbor_bool!(true).extract_undefined(), None);
659
        assert_eq!(cbor_null!().extract_undefined(), None);
660
        assert_eq!(cbor_undefined!().extract_undefined(), Some(()));
661
    }
662
663
    #[test]
664
    fn test_value_ordering() {
665
        assert!(cbor_int!(0) < cbor_int!(23));
666
        assert!(cbor_int!(23) < cbor_int!(24));
667
        assert!(cbor_int!(24) < cbor_int!(1000));
668
        assert!(cbor_int!(1000) < cbor_int!(1000000));
669
        assert!(cbor_int!(1000000) < cbor_int!(core::i64::MAX));
670
        assert!(cbor_int!(core::i64::MAX) < cbor_int!(-1));
671
        assert!(cbor_int!(-1) < cbor_int!(-23));
672
        assert!(cbor_int!(-23) < cbor_int!(-24));
673
        assert!(cbor_int!(-24) < cbor_int!(-1000));
674
        assert!(cbor_int!(-1000) < cbor_int!(-1000000));
675
        assert!(cbor_int!(-1000000) < cbor_int!(core::i64::MIN));
676
        assert!(cbor_int!(core::i64::MIN) < cbor_bytes!(vec![]));
677
        assert!(cbor_bytes!(vec![]) < cbor_bytes!(vec![0x00]));
678
        assert!(cbor_bytes!(vec![0x00]) < cbor_bytes!(vec![0x01]));
679
        assert!(cbor_bytes!(vec![0x01]) < cbor_bytes!(vec![0xFF]));
680
        assert!(cbor_bytes!(vec![0xFF]) < cbor_bytes!(vec![0x00, 0x00]));
681
        assert!(cbor_bytes!(vec![0x00, 0x00]) < cbor_text!(""));
682
        assert!(cbor_text!("") < cbor_text!("a"));
683
        assert!(cbor_text!("a") < cbor_text!("b"));
684
        assert!(cbor_text!("b") < cbor_text!("aa"));
685
        assert!(cbor_text!("aa") < cbor_array![]);
686
        assert!(cbor_array![] < cbor_array![0]);
687
        assert!(cbor_array![0] < cbor_array![-1]);
688
        assert!(cbor_array![1] < cbor_array![b""]);
689
        assert!(cbor_array![b""] < cbor_array![""]);
690
        assert!(cbor_array![""] < cbor_array![cbor_array![]]);
691
        assert!(cbor_array![cbor_array![]] < cbor_array![cbor_map! {}]);
692
        assert!(cbor_array![cbor_map! {}] < cbor_array![false]);
693
        assert!(cbor_array![false] < cbor_array![0, 0]);
694
        assert!(cbor_array![0, 0] < cbor_map! {});
695
        assert!(cbor_map! {} < cbor_map! {0 => 0});
696
        assert!(cbor_map! {0 => 0} < cbor_map! {0 => 1});
697
        assert!(cbor_map! {0 => 1} < cbor_map! {1 => 0});
698
        assert!(cbor_map! {1 => 0} < cbor_map! {-1 => 0});
699
        assert!(cbor_map! {-1 => 0} < cbor_map! {b"" => 0});
700
        assert!(cbor_map! {b"" => 0} < cbor_map! {"" => 0});
701
        assert!(cbor_map! {"" => 0} < cbor_map! {cbor_array![] => 0});
702
        assert!(cbor_map! {cbor_array![] => 0} < cbor_map! {cbor_map!{} => 0});
703
        assert!(cbor_map! {cbor_map!{} => 0} < cbor_map! {false => 0});
704
        assert!(cbor_map! {false => 0} < cbor_map! {0 => 0, 1 => 0});
705
        assert!(cbor_map! {0 => 0} < cbor_tagged!(2, cbor_int!(0)));
706
        assert!(cbor_map! {0 => 0, 1 => 0} < cbor_bool!(false));
707
        assert!(cbor_bool!(false) < cbor_bool!(true));
708
        assert!(cbor_bool!(true) < cbor_null!());
709
        assert!(cbor_null!() < cbor_undefined!());
710
        assert!(cbor_tagged!(1, cbor_text!("s")) < cbor_tagged!(2, cbor_int!(0)));
711
        assert!(cbor_int!(1) < cbor_int!(-1));
712
        assert!(cbor_int!(1) < cbor_bytes!(vec![0x00]));
713
        assert!(cbor_int!(1) < cbor_text!("s"));
714
        assert!(cbor_int!(1) < cbor_array![]);
715
        assert!(cbor_int!(1) < cbor_map! {});
716
        assert!(cbor_int!(1) < cbor_tagged!(1, cbor_text!("s")));
717
        assert!(cbor_int!(1) < cbor_bool!(false));
718
        assert!(cbor_int!(-1) < cbor_bytes!(vec![0x00]));
719
        assert!(cbor_int!(-1) < cbor_text!("s"));
720
        assert!(cbor_int!(-1) < cbor_array![]);
721
        assert!(cbor_int!(-1) < cbor_map! {});
722
        assert!(cbor_int!(-1) < cbor_tagged!(1, cbor_text!("s")));
723
        assert!(cbor_int!(-1) < cbor_bool!(false));
724
        assert!(cbor_bytes!(vec![0x00]) < cbor_text!("s"));
725
        assert!(cbor_bytes!(vec![0x00]) < cbor_array![]);
726
        assert!(cbor_bytes!(vec![0x00]) < cbor_map! {});
727
        assert!(cbor_bytes!(vec![0x00]) < cbor_tagged!(1, cbor_text!("s")));
728
        assert!(cbor_bytes!(vec![0x00]) < cbor_bool!(false));
729
        assert!(cbor_text!("s") < cbor_array![]);
730
        assert!(cbor_text!("s") < cbor_map! {});
731
        assert!(cbor_text!("s") < cbor_tagged!(1, cbor_text!("s")));
732
        assert!(cbor_text!("s") < cbor_bool!(false));
733
        assert!(cbor_array![] < cbor_map!(0 => 1));
734
        assert!(cbor_array![] < cbor_tagged!(2, cbor_int!(0)));
735
        assert!(cbor_array![] < cbor_bool!(false));
736
        assert!(cbor_tagged!(1, cbor_text!("s")) < cbor_bool!(false));
737
    }
738
}