Coverage Report

Created: 2026-06-30 07:02

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.23M
    pub fn unsigned(int: u64) -> Value {
80
9.23M
        Value(ValueImpl::Unsigned(int))
81
9.23M
    }
82
83
    /// Create an appropriate CBOR integer value (uint/nint).
84
    /// For simplicity, this only takes i64. Construct directly for the last bit.
85
197k
    pub fn integer(int: i64) -> Value {
86
197k
        if int >= 0 {
87
169k
            Value(ValueImpl::Unsigned(int as u64))
88
        } else {
89
27.8k
            Value(ValueImpl::Negative(int))
90
        }
91
197k
    }
92
93
    /// Creates a CBOR byte string value.
94
935k
    pub fn byte_string(bytes: Vec<u8>) -> Value {
95
935k
        Value(ValueImpl::ByteString(bytes))
96
935k
    }
97
98
    /// Creates a CBOR text string value.
99
154k
    pub fn text_string(text: String) -> Value {
100
154k
        Value(ValueImpl::TextString(text))
101
154k
    }
102
103
    /// Create a CBOR array value.
104
1.90M
    pub fn array(a: Vec<Value>) -> Value {
105
1.90M
        Value(ValueImpl::Array(a))
106
1.90M
    }
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
418k
    pub fn map(mut m: Vec<(Value, Value)>) -> Value {
116
418k
        m.sort_by(|a, b| a.0.cmp(&b.0));
117
418k
        let map_len = m.len();
118
418k
        m.dedup_by(|a, b| a.0.eq(&b.0));
119
418k
        if map_len != m.len() {
120
0
            panic!();
121
418k
        }
122
418k
        Value(ValueImpl::Map(m))
123
418k
    }
124
125
    /// Create a CBOR tagged value.
126
1.48M
    pub fn tag(int: u64, value: Value) -> Value {
127
1.48M
        Value(ValueImpl::Tag(int, Box::new(value)))
128
1.48M
    }
129
130
    /// Create a CBOR boolean simple value.
131
1.84k
    pub fn bool_value(b: bool) -> Value {
132
1.84k
        if b {
133
1.38k
            Value(ValueImpl::Simple(SimpleValue::TrueValue))
134
        } else {
135
459
            Value(ValueImpl::Simple(SimpleValue::FalseValue))
136
        }
137
1.84k
    }
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
11.6k
    pub fn extract_unsigned(self) -> Option<u64> {
150
11.6k
        match self {
151
11.4k
            Value(ValueImpl::Unsigned(unsigned)) => Some(unsigned),
152
140
            _ => None,
153
        }
154
11.6k
    }
155
156
4.72k
    pub fn extract_integer(self) -> Option<i64> {
157
4.72k
        match self {
158
1.02k
            Value(ValueImpl::Unsigned(unsigned)) => {
159
1.02k
                if unsigned <= i64::MAX as u64 {
160
745
                    Some(unsigned as i64)
161
                } else {
162
280
                    None
163
                }
164
            }
165
3.66k
            Value(ValueImpl::Negative(signed)) => Some(signed),
166
37
            _ => None,
167
        }
168
4.72k
    }
169
170
20.9k
    pub fn extract_byte_string(self) -> Option<Vec<u8>> {
171
20.9k
        match self {
172
20.8k
            Value(ValueImpl::ByteString(byte_string)) => Some(byte_string),
173
178
            _ => None,
174
        }
175
20.9k
    }
176
177
22.2k
    pub fn extract_text_string(self) -> Option<String> {
178
22.2k
        match self {
179
22.0k
            Value(ValueImpl::TextString(text_string)) => Some(text_string),
180
179
            _ => None,
181
        }
182
22.2k
    }
183
184
7.96k
    pub fn extract_array(self) -> Option<Vec<Value>> {
185
7.96k
        match self {
186
7.92k
            Value(ValueImpl::Array(array)) => Some(array),
187
36
            _ => None,
188
        }
189
7.96k
    }
190
191
40.3k
    pub fn extract_map(self) -> Option<Vec<(Value, Value)>> {
192
40.3k
        match self {
193
39.4k
            Value(ValueImpl::Map(map)) => Some(map),
194
963
            _ => None,
195
        }
196
40.3k
    }
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
963
    pub fn extract_bool(self) -> Option<bool> {
206
832
        match self {
207
35
            Value(ValueImpl::Simple(SimpleValue::FalseValue)) => Some(false),
208
782
            Value(ValueImpl::Simple(SimpleValue::TrueValue)) => Some(true),
209
146
            _ => None,
210
        }
211
963
    }
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
8.93M
    pub fn type_label(&self) -> u8 {
231
        // TODO use enum discriminant instead when stable
232
        // https://github.com/rust-lang/rust/issues/60553
233
8.93M
        match self {
234
1.82M
            ValueImpl::Unsigned(_) => 0,
235
2.23M
            ValueImpl::Negative(_) => 1,
236
1.50M
            ValueImpl::ByteString(_) => 2,
237
240k
            ValueImpl::TextString(_) => 3,
238
553k
            ValueImpl::Array(_) => 4,
239
391k
            ValueImpl::Map(_) => 5,
240
2.13M
            ValueImpl::Tag(_, _) => 6,
241
50.3k
            ValueImpl::Simple(_) => 7,
242
        }
243
8.93M
    }
244
}
245
246
impl Ord for ValueImpl {
247
1.25M
    fn cmp(&self, other: &ValueImpl) -> Ordering {
248
        use super::values::ValueImpl::{
249
            Array, ByteString, Map, Negative, Simple, Tag, TextString, Unsigned,
250
        };
251
1.25M
        let self_type_value = self.type_label();
252
1.25M
        let other_type_value = other.type_label();
253
1.25M
        if self_type_value != other_type_value {
254
786k
            return self_type_value.cmp(&other_type_value);
255
466k
        }
256
466k
        match (self, other) {
257
248k
            (Unsigned(u1), Unsigned(u2)) => u1.cmp(u2),
258
52.1k
            (Negative(n1), Negative(n2)) => n1.cmp(n2).reverse(),
259
40.1k
            (ByteString(b1), ByteString(b2)) => b1.len().cmp(&b2.len()).then(b1.cmp(b2)),
260
76.5k
            (TextString(t1), TextString(t2)) => t1.len().cmp(&t2.len()).then(t1.cmp(t2)),
261
6.94k
            (Array(a1), Array(a2)) if a1.len() != a2.len() => a1.len().cmp(&a2.len()),
262
4.43k
            (Array(a1), Array(a2)) => {
263
                // Arrays of same length.
264
4.43k
                let mut ordering = Ordering::Equal;
265
7.41k
                for (e1, e2) in a1.iter().zip(a2.iter()) {
266
7.41k
                    ordering = e1.cmp(e2);
267
7.41k
                    if !matches!(ordering, Ordering::Equal) {
268
2.38k
                        break;
269
5.03k
                    }
270
                }
271
4.43k
                ordering
272
            }
273
11.9k
            (Map(m1), Map(m2)) if m1.len() != m2.len() => m1.len().cmp(&m2.len()),
274
8.66k
            (Map(m1), Map(m2)) => {
275
                // Maps of same length.
276
8.66k
                let mut ordering = Ordering::Equal;
277
9.58k
                for ((k1, v1), (k2, v2)) in m1.iter().zip(m2.iter()) {
278
9.58k
                    ordering = k1.cmp(k2).then_with(|| v1.cmp(v2));
279
9.58k
                    if !matches!(ordering, Ordering::Equal) {
280
4.71k
                        break;
281
4.86k
                    }
282
                }
283
8.66k
                ordering
284
            }
285
23.9k
            (Tag(t1, v1), Tag(t2, v2)) => t1.cmp(t2).then(v1.cmp(v2)),
286
6.12k
            (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.25M
    }
293
}
294
295
impl PartialOrd for ValueImpl {
296
335k
    fn partial_cmp(&self, other: &ValueImpl) -> Option<Ordering> {
297
335k
        Some(self.cmp(other))
298
335k
    }
299
}
300
301
impl Eq for ValueImpl {}
302
303
impl PartialEq for ValueImpl {
304
369k
    fn eq(&self, other: &ValueImpl) -> bool {
305
369k
        self.cmp(other) == Ordering::Equal
306
369k
    }
307
}
308
309
impl SimpleValue {
310
    /// Create a simple value from its encoded value.
311
43.7k
    pub fn from_integer(int: u64) -> Option<SimpleValue> {
312
43.7k
        match int {
313
3.59k
            20 => Some(SimpleValue::FalseValue),
314
5.69k
            21 => Some(SimpleValue::TrueValue),
315
11.5k
            22 => Some(SimpleValue::NullValue),
316
22.8k
            23 => Some(SimpleValue::Undefined),
317
82
            _ => None,
318
        }
319
43.7k
    }
320
}
321
322
impl From<u64> for Value {
323
16.6k
    fn from(u: u64) -> Self {
324
16.6k
        Value::unsigned(u)
325
16.6k
    }
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
17.4k
    fn from(i: i64) -> Self {
348
17.4k
        Value::integer(i)
349
17.4k
    }
350
}
351
352
impl From<i32> for Value {
353
176k
    fn from(i: i32) -> Self {
354
176k
        Value::integer(i as i64)
355
176k
    }
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
11.4k
    fn from(bytes: Vec<u8>) -> Self {
372
11.4k
        Value(ValueImpl::ByteString(bytes))
373
11.4k
    }
374
}
375
376
impl From<&[u8]> for Value {
377
8.09k
    fn from(bytes: &[u8]) -> Self {
378
8.09k
        Value(ValueImpl::ByteString(bytes.to_vec()))
379
8.09k
    }
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
5.96k
    fn from(text: String) -> Self {
390
5.96k
        Value(ValueImpl::TextString(text))
391
5.96k
    }
392
}
393
394
impl From<&str> for Value {
395
69.6k
    fn from(text: &str) -> Self {
396
69.6k
        Value(ValueImpl::TextString(text.to_string()))
397
69.6k
    }
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
869
    fn from(b: bool) -> Self {
414
869
        Value::bool_value(b)
415
869
    }
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.85M
    fn into_cbor_value(self) -> Value {
429
7.85M
        Value::from(self)
430
7.85M
    }
<opensk::api::key_store::CredentialSourceField as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
5.88k
    fn into_cbor_value(self) -> Value {
429
5.88k
        Value::from(self)
430
5.88k
    }
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
89
    fn into_cbor_value(self) -> Value {
429
89
        Value::from(self)
430
89
    }
<opensk::ctap::data_formats::PublicKeyCredentialParameter as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
89
    fn into_cbor_value(self) -> Value {
429
89
        Value::from(self)
430
89
    }
<opensk::ctap::data_formats::PublicKeyCredentialSourceField as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
8.45k
    fn into_cbor_value(self) -> Value {
429
8.45k
        Value::from(self)
430
8.45k
    }
<alloc::string::String as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
1.85k
    fn into_cbor_value(self) -> Value {
429
1.85k
        Value::from(self)
430
1.85k
    }
<&str as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
69.4k
    fn into_cbor_value(self) -> Value {
429
69.4k
        Value::from(self)
430
69.4k
    }
<i32 as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
176k
    fn into_cbor_value(self) -> Value {
429
176k
        Value::from(self)
430
176k
    }
<u64 as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
178
    fn into_cbor_value(self) -> Value {
429
178
        Value::from(self)
430
178
    }
<sk_cbor::values::Value as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
7.59M
    fn into_cbor_value(self) -> Value {
429
7.59M
        Value::from(self)
430
7.59M
    }
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
36.6k
    fn into_cbor_value_option(self) -> Option<Value> {
444
36.6k
        Some(Value::from(self))
445
36.6k
    }
<alloc::vec::Vec<u8> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
3.08k
    fn into_cbor_value_option(self) -> Option<Value> {
444
3.08k
        Some(Value::from(self))
445
3.08k
    }
<opensk::ctap::data_formats::SignatureAlgorithm as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
89
    fn into_cbor_value_option(self) -> Option<Value> {
444
89
        Some(Value::from(self))
445
89
    }
<opensk::ctap::data_formats::PublicKeyCredentialType as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
89
    fn into_cbor_value_option(self) -> Option<Value> {
444
89
        Some(Value::from(self))
445
89
    }
<opensk::ctap::data_formats::PackedAttestationStatement as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
1.40k
    fn into_cbor_value_option(self) -> Option<Value> {
444
1.40k
        Some(Value::from(self))
445
1.40k
    }
<alloc::string::String as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
1.40k
    fn into_cbor_value_option(self) -> Option<Value> {
444
1.40k
        Some(Value::from(self))
445
1.40k
    }
<sk_cbor::values::Value as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
4.19k
    fn into_cbor_value_option(self) -> Option<Value> {
444
4.19k
        Some(Value::from(self))
445
4.19k
    }
<&[u8] as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
8.09k
    fn into_cbor_value_option(self) -> Option<Value> {
444
8.09k
        Some(Value::from(self))
445
8.09k
    }
<i64 as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
16.8k
    fn into_cbor_value_option(self) -> Option<Value> {
444
16.8k
        Some(Value::from(self))
445
16.8k
    }
<u64 as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
1.35k
    fn into_cbor_value_option(self) -> Option<Value> {
444
1.35k
        Some(Value::from(self))
445
1.35k
    }
446
}
447
448
impl<T> IntoCborValueOption for Option<T>
449
where
450
    Value: From<T>,
451
{
452
39.1k
    fn into_cbor_value_option(self) -> Option<Value> {
453
39.1k
        self.map(Value::from)
454
39.1k
    }
<core::option::Option<alloc::vec::Vec<u8>> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
17.3k
    fn into_cbor_value_option(self) -> Option<Value> {
453
17.3k
        self.map(Value::from)
454
17.3k
    }
<core::option::Option<sk_cbor::values::Value> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
3.41k
    fn into_cbor_value_option(self) -> Option<Value> {
453
3.41k
        self.map(Value::from)
454
3.41k
    }
<core::option::Option<alloc::string::String> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
5.10k
    fn into_cbor_value_option(self) -> Option<Value> {
453
5.10k
        self.map(Value::from)
454
5.10k
    }
<core::option::Option<opensk::ctap::data_formats::CredentialProtectionPolicy> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
4.66k
    fn into_cbor_value_option(self) -> Option<Value> {
453
4.66k
        self.map(Value::from)
454
4.66k
    }
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
38
    fn into_cbor_value_option(self) -> Option<Value> {
453
38
        self.map(Value::from)
454
38
    }
<core::option::Option<opensk::ctap::data_formats::PublicKeyCredentialUserEntity> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
38
    fn into_cbor_value_option(self) -> Option<Value> {
453
38
        self.map(Value::from)
454
38
    }
<core::option::Option<bool> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
4.08k
    fn into_cbor_value_option(self) -> Option<Value> {
453
4.08k
        self.map(Value::from)
454
4.08k
    }
<core::option::Option<u64> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
4.39k
    fn into_cbor_value_option(self) -> Option<Value> {
453
4.39k
        self.map(Value::from)
454
4.39k
    }
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
}