Coverage Report

Created: 2026-11-12 06:16

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
8.22M
    pub fn unsigned(int: u64) -> Value {
80
8.22M
        Value(ValueImpl::Unsigned(int))
81
8.22M
    }
82
83
    /// Create an appropriate CBOR integer value (uint/nint).
84
    /// For simplicity, this only takes i64. Construct directly for the last bit.
85
129k
    pub fn integer(int: i64) -> Value {
86
129k
        if int >= 0 {
87
113k
            Value(ValueImpl::Unsigned(int as u64))
88
        } else {
89
16.7k
            Value(ValueImpl::Negative(int))
90
        }
91
129k
    }
92
93
    /// Creates a CBOR byte string value.
94
1.03M
    pub fn byte_string(bytes: Vec<u8>) -> Value {
95
1.03M
        Value(ValueImpl::ByteString(bytes))
96
1.03M
    }
97
98
    /// Creates a CBOR text string value.
99
139k
    pub fn text_string(text: String) -> Value {
100
139k
        Value(ValueImpl::TextString(text))
101
139k
    }
102
103
    /// Create a CBOR array value.
104
1.92M
    pub fn array(a: Vec<Value>) -> Value {
105
1.92M
        Value(ValueImpl::Array(a))
106
1.92M
    }
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
403k
    pub fn map(mut m: Vec<(Value, Value)>) -> Value {
116
403k
        m.sort_by(|a, b| a.0.cmp(&b.0));
117
403k
        let map_len = m.len();
118
403k
        m.dedup_by(|a, b| a.0.eq(&b.0));
119
403k
        if map_len != m.len() {
120
0
            panic!();
121
403k
        }
122
403k
        Value(ValueImpl::Map(m))
123
403k
    }
124
125
    /// Create a CBOR tagged value.
126
1.52M
    pub fn tag(int: u64, value: Value) -> Value {
127
1.52M
        Value(ValueImpl::Tag(int, Box::new(value)))
128
1.52M
    }
129
130
    /// Create a CBOR boolean simple value.
131
1.44k
    pub fn bool_value(b: bool) -> Value {
132
1.44k
        if b {
133
1.05k
            Value(ValueImpl::Simple(SimpleValue::TrueValue))
134
        } else {
135
386
            Value(ValueImpl::Simple(SimpleValue::FalseValue))
136
        }
137
1.44k
    }
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
9.20k
    pub fn extract_unsigned(self) -> Option<u64> {
150
9.20k
        match self {
151
9.09k
            Value(ValueImpl::Unsigned(unsigned)) => Some(unsigned),
152
109
            _ => None,
153
        }
154
9.20k
    }
155
156
2.46k
    pub fn extract_integer(self) -> Option<i64> {
157
2.46k
        match self {
158
592
            Value(ValueImpl::Unsigned(unsigned)) => {
159
592
                if unsigned <= i64::MAX as u64 {
160
393
                    Some(unsigned as i64)
161
                } else {
162
199
                    None
163
                }
164
            }
165
1.84k
            Value(ValueImpl::Negative(signed)) => Some(signed),
166
22
            _ => None,
167
        }
168
2.46k
    }
169
170
14.7k
    pub fn extract_byte_string(self) -> Option<Vec<u8>> {
171
14.7k
        match self {
172
14.6k
            Value(ValueImpl::ByteString(byte_string)) => Some(byte_string),
173
167
            _ => None,
174
        }
175
14.7k
    }
176
177
14.3k
    pub fn extract_text_string(self) -> Option<String> {
178
14.3k
        match self {
179
14.1k
            Value(ValueImpl::TextString(text_string)) => Some(text_string),
180
147
            _ => None,
181
        }
182
14.3k
    }
183
184
4.39k
    pub fn extract_array(self) -> Option<Vec<Value>> {
185
4.39k
        match self {
186
4.35k
            Value(ValueImpl::Array(array)) => Some(array),
187
35
            _ => None,
188
        }
189
4.39k
    }
190
191
26.7k
    pub fn extract_map(self) -> Option<Vec<(Value, Value)>> {
192
26.7k
        match self {
193
26.0k
            Value(ValueImpl::Map(map)) => Some(map),
194
768
            _ => None,
195
        }
196
26.7k
    }
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
513
    pub fn extract_bool(self) -> Option<bool> {
206
439
        match self {
207
32
            Value(ValueImpl::Simple(SimpleValue::FalseValue)) => Some(false),
208
400
            Value(ValueImpl::Simple(SimpleValue::TrueValue)) => Some(true),
209
81
            _ => None,
210
        }
211
513
    }
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.81M
    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.81M
        match self {
234
1.74M
            ValueImpl::Unsigned(_) => 0,
235
2.04M
            ValueImpl::Negative(_) => 1,
236
1.58M
            ValueImpl::ByteString(_) => 2,
237
207k
            ValueImpl::TextString(_) => 3,
238
627k
            ValueImpl::Array(_) => 4,
239
385k
            ValueImpl::Map(_) => 5,
240
2.16M
            ValueImpl::Tag(_, _) => 6,
241
48.3k
            ValueImpl::Simple(_) => 7,
242
        }
243
8.81M
    }
244
}
245
246
impl Ord for ValueImpl {
247
1.13M
    fn cmp(&self, other: &ValueImpl) -> Ordering {
248
        use super::values::ValueImpl::{
249
            Array, ByteString, Map, Negative, Simple, Tag, TextString, Unsigned,
250
        };
251
1.13M
        let self_type_value = self.type_label();
252
1.13M
        let other_type_value = other.type_label();
253
1.13M
        if self_type_value != other_type_value {
254
768k
            return self_type_value.cmp(&other_type_value);
255
364k
        }
256
364k
        match (self, other) {
257
180k
            (Unsigned(u1), Unsigned(u2)) => u1.cmp(u2),
258
43.2k
            (Negative(n1), Negative(n2)) => n1.cmp(n2).reverse(),
259
36.1k
            (ByteString(b1), ByteString(b2)) => b1.len().cmp(&b2.len()).then(b1.cmp(b2)),
260
61.1k
            (TextString(t1), TextString(t2)) => t1.len().cmp(&t2.len()).then(t1.cmp(t2)),
261
7.35k
            (Array(a1), Array(a2)) if a1.len() != a2.len() => a1.len().cmp(&a2.len()),
262
5.16k
            (Array(a1), Array(a2)) => {
263
                // Arrays of same length.
264
5.16k
                let mut ordering = Ordering::Equal;
265
8.05k
                for (e1, e2) in a1.iter().zip(a2.iter()) {
266
8.05k
                    ordering = e1.cmp(e2);
267
8.05k
                    if !matches!(ordering, Ordering::Equal) {
268
2.31k
                        break;
269
5.74k
                    }
270
                }
271
5.16k
                ordering
272
            }
273
12.0k
            (Map(m1), Map(m2)) if m1.len() != m2.len() => m1.len().cmp(&m2.len()),
274
8.40k
            (Map(m1), Map(m2)) => {
275
                // Maps of same length.
276
8.40k
                let mut ordering = Ordering::Equal;
277
9.68k
                for ((k1, v1), (k2, v2)) in m1.iter().zip(m2.iter()) {
278
9.68k
                    ordering = k1.cmp(k2).then_with(|| v1.cmp(v2));
279
9.68k
                    if !matches!(ordering, Ordering::Equal) {
280
4.59k
                        break;
281
5.08k
                    }
282
                }
283
8.40k
                ordering
284
            }
285
18.5k
            (Tag(t1, v1), Tag(t2, v2)) => t1.cmp(t2).then(v1.cmp(v2)),
286
5.48k
            (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.13M
    }
293
}
294
295
impl PartialOrd for ValueImpl {
296
317k
    fn partial_cmp(&self, other: &ValueImpl) -> Option<Ordering> {
297
317k
        Some(self.cmp(other))
298
317k
    }
299
}
300
301
impl Eq for ValueImpl {}
302
303
impl PartialEq for ValueImpl {
304
336k
    fn eq(&self, other: &ValueImpl) -> bool {
305
336k
        self.cmp(other) == Ordering::Equal
306
336k
    }
307
}
308
309
impl SimpleValue {
310
    /// Create a simple value from its encoded value.
311
46.0k
    pub fn from_integer(int: u64) -> Option<SimpleValue> {
312
46.0k
        match int {
313
3.70k
            20 => Some(SimpleValue::FalseValue),
314
4.92k
            21 => Some(SimpleValue::TrueValue),
315
10.1k
            22 => Some(SimpleValue::NullValue),
316
27.1k
            23 => Some(SimpleValue::Undefined),
317
75
            _ => None,
318
        }
319
46.0k
    }
320
}
321
322
impl From<u64> for Value {
323
10.8k
    fn from(u: u64) -> Self {
324
10.8k
        Value::unsigned(u)
325
10.8k
    }
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
10.1k
    fn from(i: i64) -> Self {
348
10.1k
        Value::integer(i)
349
10.1k
    }
350
}
351
352
impl From<i32> for Value {
353
117k
    fn from(i: i32) -> Self {
354
117k
        Value::integer(i as i64)
355
117k
    }
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
6.84k
    fn from(bytes: Vec<u8>) -> Self {
372
6.84k
        Value(ValueImpl::ByteString(bytes))
373
6.84k
    }
374
}
375
376
impl From<&[u8]> for Value {
377
4.61k
    fn from(bytes: &[u8]) -> Self {
378
4.61k
        Value(ValueImpl::ByteString(bytes.to_vec()))
379
4.61k
    }
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.36k
    fn from(text: String) -> Self {
390
4.36k
        Value(ValueImpl::TextString(text))
391
4.36k
    }
392
}
393
394
impl From<&str> for Value {
395
41.9k
    fn from(text: &str) -> Self {
396
41.9k
        Value(ValueImpl::TextString(text.to_string()))
397
41.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
725
    fn from(b: bool) -> Self {
414
725
        Value::bool_value(b)
415
725
    }
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
8.07M
    fn into_cbor_value(self) -> Value {
429
8.07M
        Value::from(self)
430
8.07M
    }
<opensk::api::key_store::CredentialSourceField as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
3.21k
    fn into_cbor_value(self) -> Value {
429
3.21k
        Value::from(self)
430
3.21k
    }
<alloc::string::String as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
1.09k
    fn into_cbor_value(self) -> Value {
429
1.09k
        Value::from(self)
430
1.09k
    }
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
65
    fn into_cbor_value(self) -> Value {
429
65
        Value::from(self)
430
65
    }
<opensk::ctap::data_formats::PublicKeyCredentialParameter as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
65
    fn into_cbor_value(self) -> Value {
429
65
        Value::from(self)
430
65
    }
<opensk::ctap::data_formats::PublicKeyCredentialSourceField as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
5.96k
    fn into_cbor_value(self) -> Value {
429
5.96k
        Value::from(self)
430
5.96k
    }
<&str as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
41.7k
    fn into_cbor_value(self) -> Value {
429
41.7k
        Value::from(self)
430
41.7k
    }
<i32 as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
117k
    fn into_cbor_value(self) -> Value {
429
117k
        Value::from(self)
430
117k
    }
<u64 as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
130
    fn into_cbor_value(self) -> Value {
429
130
        Value::from(self)
430
130
    }
<sk_cbor::values::Value as sk_cbor::values::IntoCborValue>::into_cbor_value
Line
Count
Source
428
7.90M
    fn into_cbor_value(self) -> Value {
429
7.90M
        Value::from(self)
430
7.90M
    }
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
20.7k
    fn into_cbor_value_option(self) -> Option<Value> {
444
20.7k
        Some(Value::from(self))
445
20.7k
    }
<alloc::string::String as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
674
    fn into_cbor_value_option(self) -> Option<Value> {
444
674
        Some(Value::from(self))
445
674
    }
<alloc::vec::Vec<u8> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
1.53k
    fn into_cbor_value_option(self) -> Option<Value> {
444
1.53k
        Some(Value::from(self))
445
1.53k
    }
<opensk::ctap::data_formats::SignatureAlgorithm as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
65
    fn into_cbor_value_option(self) -> Option<Value> {
444
65
        Some(Value::from(self))
445
65
    }
<opensk::ctap::data_formats::PublicKeyCredentialType as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
65
    fn into_cbor_value_option(self) -> Option<Value> {
444
65
        Some(Value::from(self))
445
65
    }
<opensk::ctap::data_formats::PackedAttestationStatement as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
674
    fn into_cbor_value_option(self) -> Option<Value> {
444
674
        Some(Value::from(self))
445
674
    }
<sk_cbor::values::Value as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
2.44k
    fn into_cbor_value_option(self) -> Option<Value> {
444
2.44k
        Some(Value::from(self))
445
2.44k
    }
<&[u8] as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
4.61k
    fn into_cbor_value_option(self) -> Option<Value> {
444
4.61k
        Some(Value::from(self))
445
4.61k
    }
<i64 as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
9.73k
    fn into_cbor_value_option(self) -> Option<Value> {
444
9.73k
        Some(Value::from(self))
445
9.73k
    }
<u64 as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
443
911
    fn into_cbor_value_option(self) -> Option<Value> {
444
911
        Some(Value::from(self))
445
911
    }
446
}
447
448
impl<T> IntoCborValueOption for Option<T>
449
where
450
    Value: From<T>,
451
{
452
24.3k
    fn into_cbor_value_option(self) -> Option<Value> {
453
24.3k
        self.map(Value::from)
454
24.3k
    }
<core::option::Option<alloc::vec::Vec<u8>> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
10.3k
    fn into_cbor_value_option(self) -> Option<Value> {
453
10.3k
        self.map(Value::from)
454
10.3k
    }
<core::option::Option<sk_cbor::values::Value> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
2.05k
    fn into_cbor_value_option(self) -> Option<Value> {
453
2.05k
        self.map(Value::from)
454
2.05k
    }
<core::option::Option<alloc::string::String> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
3.44k
    fn into_cbor_value_option(self) -> Option<Value> {
453
3.44k
        self.map(Value::from)
454
3.44k
    }
<core::option::Option<opensk::ctap::data_formats::CredentialProtectionPolicy> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
2.81k
    fn into_cbor_value_option(self) -> Option<Value> {
453
2.81k
        self.map(Value::from)
454
2.81k
    }
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
49
    fn into_cbor_value_option(self) -> Option<Value> {
453
49
        self.map(Value::from)
454
49
    }
<core::option::Option<opensk::ctap::data_formats::PublicKeyCredentialUserEntity> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
49
    fn into_cbor_value_option(self) -> Option<Value> {
453
49
        self.map(Value::from)
454
49
    }
<core::option::Option<bool> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
2.60k
    fn into_cbor_value_option(self) -> Option<Value> {
453
2.60k
        self.map(Value::from)
454
2.60k
    }
<core::option::Option<u64> as sk_cbor::values::IntoCborValueOption>::into_cbor_value_option
Line
Count
Source
452
3.06k
    fn into_cbor_value_option(self) -> Option<Value> {
453
3.06k
        self.map(Value::from)
454
3.06k
    }
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!(cbor_unsigned!(u64::MAX).extract_unsigned(), Some(u64::MAX));
493
        assert_eq!(
494
            cbor_unsigned!((i64::MAX as u64) + 1).extract_unsigned(),
495
            Some((i64::MAX as u64) + 1)
496
        );
497
        assert_eq!(
498
            cbor_int!(i64::MAX).extract_unsigned(),
499
            Some(i64::MAX as u64)
500
        );
501
        assert_eq!(cbor_int!(123).extract_unsigned(), Some(123));
502
        assert_eq!(cbor_int!(0).extract_unsigned(), Some(0));
503
        assert_eq!(cbor_int!(-123).extract_unsigned(), None);
504
        assert_eq!(cbor_int!(i64::MIN).extract_unsigned(), None);
505
    }
506
507
    #[test]
508
    fn test_extract_integer() {
509
        assert_eq!(cbor_int!(1).extract_integer(), Some(1));
510
        assert_eq!(cbor_int!(-1).extract_integer(), Some(-1));
511
        assert_eq!(cbor_bytes!(vec![]).extract_integer(), None);
512
        assert_eq!(cbor_text!("").extract_integer(), None);
513
        assert_eq!(cbor_array![].extract_integer(), None);
514
        assert_eq!(cbor_map! {}.extract_integer(), None);
515
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_integer(), None);
516
        assert_eq!(cbor_bool!(false).extract_integer(), None);
517
    }
518
519
    #[test]
520
    fn test_extract_integer_limits() {
521
        assert_eq!(cbor_unsigned!(u64::MAX).extract_integer(), None);
522
        assert_eq!(
523
            cbor_unsigned!((i64::MAX as u64) + 1).extract_integer(),
524
            None
525
        );
526
        assert_eq!(cbor_int!(i64::MAX).extract_integer(), Some(i64::MAX));
527
        assert_eq!(cbor_int!(123).extract_integer(), Some(123));
528
        assert_eq!(cbor_int!(0).extract_integer(), Some(0));
529
        assert_eq!(cbor_int!(-123).extract_integer(), Some(-123));
530
        assert_eq!(cbor_int!(i64::MIN).extract_integer(), Some(i64::MIN));
531
    }
532
533
    #[test]
534
    fn test_extract_byte_string() {
535
        assert_eq!(cbor_int!(1).extract_byte_string(), None);
536
        assert_eq!(cbor_int!(-1).extract_byte_string(), None);
537
        assert_eq!(cbor_bytes!(vec![]).extract_byte_string(), Some(Vec::new()));
538
        assert_eq!(
539
            cbor_bytes_lit!(b"bar").extract_byte_string(),
540
            Some(b"bar".to_vec())
541
        );
542
        assert_eq!(cbor_text!("").extract_byte_string(), None);
543
        assert_eq!(cbor_array![].extract_byte_string(), None);
544
        assert_eq!(cbor_map! {}.extract_byte_string(), None);
545
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_byte_string(), None);
546
        assert_eq!(cbor_bool!(false).extract_byte_string(), None);
547
    }
548
549
    #[test]
550
    fn test_extract_text_string() {
551
        assert_eq!(cbor_int!(1).extract_text_string(), None);
552
        assert_eq!(cbor_int!(-1).extract_text_string(), None);
553
        assert_eq!(cbor_bytes!(vec![]).extract_text_string(), None);
554
        assert_eq!(cbor_text!("").extract_text_string(), Some(String::new()));
555
        assert_eq!(cbor_text!("s").extract_text_string(), Some("s".to_string()));
556
        assert_eq!(cbor_array![].extract_text_string(), None);
557
        assert_eq!(cbor_map! {}.extract_text_string(), None);
558
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_text_string(), None);
559
        assert_eq!(cbor_bool!(false).extract_text_string(), None);
560
    }
561
562
    #[test]
563
    fn test_extract_array() {
564
        assert_eq!(cbor_int!(1).extract_array(), None);
565
        assert_eq!(cbor_int!(-1).extract_array(), None);
566
        assert_eq!(cbor_bytes!(vec![]).extract_array(), None);
567
        assert_eq!(cbor_text!("").extract_array(), None);
568
        assert_eq!(cbor_array![].extract_array(), Some(Vec::new()));
569
        assert_eq!(
570
            cbor_array![cbor_int!(1)].extract_array(),
571
            Some(vec![cbor_int!(1)])
572
        );
573
        assert_eq!(cbor_map! {}.extract_array(), None);
574
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_array(), None);
575
        assert_eq!(cbor_bool!(false).extract_array(), None);
576
    }
577
578
    #[test]
579
    fn test_extract_map() {
580
        assert_eq!(cbor_int!(1).extract_map(), None);
581
        assert_eq!(cbor_int!(-1).extract_map(), None);
582
        assert_eq!(cbor_bytes!(vec![]).extract_map(), None);
583
        assert_eq!(cbor_text!("").extract_map(), None);
584
        assert_eq!(cbor_array![].extract_map(), None);
585
        assert_eq!(cbor_map! {}.extract_map(), Some(Vec::new()));
586
        assert_eq!(
587
            cbor_map! {0 => 1}.extract_map(),
588
            Some(vec![(cbor_int!(0), cbor_int!(1))])
589
        );
590
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_map(), None);
591
        assert_eq!(cbor_bool!(false).extract_map(), None);
592
    }
593
594
    #[test]
595
    fn test_extract_tag() {
596
        assert_eq!(cbor_int!(1).extract_tag(), None);
597
        assert_eq!(cbor_int!(-1).extract_tag(), None);
598
        assert_eq!(cbor_bytes!(vec![]).extract_tag(), None);
599
        assert_eq!(cbor_text!("").extract_tag(), None);
600
        assert_eq!(cbor_array![].extract_tag(), None);
601
        assert_eq!(cbor_map! {}.extract_tag(), None);
602
        assert_eq!(
603
            cbor_tagged!(1, cbor_text!("s")).extract_tag(),
604
            Some((1, cbor_text!("s")))
605
        );
606
        assert_eq!(cbor_bool!(false).extract_tag(), None);
607
    }
608
609
    #[test]
610
    fn test_extract_bool() {
611
        assert_eq!(cbor_int!(1).extract_bool(), None);
612
        assert_eq!(cbor_int!(-1).extract_bool(), None);
613
        assert_eq!(cbor_bytes!(vec![]).extract_bool(), None);
614
        assert_eq!(cbor_text!("").extract_bool(), None);
615
        assert_eq!(cbor_array![].extract_bool(), None);
616
        assert_eq!(cbor_map! {}.extract_bool(), None);
617
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_bool(), None);
618
        assert_eq!(cbor_bool!(false).extract_bool(), Some(false));
619
        assert_eq!(cbor_bool!(true).extract_bool(), Some(true));
620
        assert_eq!(cbor_null!().extract_bool(), None);
621
        assert_eq!(cbor_undefined!().extract_bool(), None);
622
    }
623
624
    #[test]
625
    fn test_extract_null() {
626
        assert_eq!(cbor_int!(1).extract_null(), None);
627
        assert_eq!(cbor_int!(-1).extract_null(), None);
628
        assert_eq!(cbor_bytes!(vec![]).extract_null(), None);
629
        assert_eq!(cbor_text!("").extract_null(), None);
630
        assert_eq!(cbor_array![].extract_null(), None);
631
        assert_eq!(cbor_map! {}.extract_null(), None);
632
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_null(), None);
633
        assert_eq!(cbor_bool!(false).extract_null(), None);
634
        assert_eq!(cbor_bool!(true).extract_null(), None);
635
        assert_eq!(cbor_null!().extract_null(), Some(()));
636
        assert_eq!(cbor_undefined!().extract_null(), None);
637
    }
638
639
    #[test]
640
    fn test_extract_undefined() {
641
        assert_eq!(cbor_int!(1).extract_undefined(), None);
642
        assert_eq!(cbor_int!(-1).extract_undefined(), None);
643
        assert_eq!(cbor_bytes!(vec![]).extract_undefined(), None);
644
        assert_eq!(cbor_text!("").extract_undefined(), None);
645
        assert_eq!(cbor_array![].extract_undefined(), None);
646
        assert_eq!(cbor_map! {}.extract_undefined(), None);
647
        assert_eq!(cbor_tagged!(1, cbor_text!("s")).extract_undefined(), None);
648
        assert_eq!(cbor_bool!(false).extract_undefined(), None);
649
        assert_eq!(cbor_bool!(true).extract_undefined(), None);
650
        assert_eq!(cbor_null!().extract_undefined(), None);
651
        assert_eq!(cbor_undefined!().extract_undefined(), Some(()));
652
    }
653
654
    #[test]
655
    fn test_value_ordering() {
656
        assert!(cbor_int!(0) < cbor_int!(23));
657
        assert!(cbor_int!(23) < cbor_int!(24));
658
        assert!(cbor_int!(24) < cbor_int!(1000));
659
        assert!(cbor_int!(1000) < cbor_int!(1000000));
660
        assert!(cbor_int!(1000000) < cbor_int!(i64::MAX));
661
        assert!(cbor_int!(i64::MAX) < cbor_int!(-1));
662
        assert!(cbor_int!(-1) < cbor_int!(-23));
663
        assert!(cbor_int!(-23) < cbor_int!(-24));
664
        assert!(cbor_int!(-24) < cbor_int!(-1000));
665
        assert!(cbor_int!(-1000) < cbor_int!(-1000000));
666
        assert!(cbor_int!(-1000000) < cbor_int!(i64::MIN));
667
        assert!(cbor_int!(i64::MIN) < cbor_bytes!(vec![]));
668
        assert!(cbor_bytes!(vec![]) < cbor_bytes!(vec![0x00]));
669
        assert!(cbor_bytes!(vec![0x00]) < cbor_bytes!(vec![0x01]));
670
        assert!(cbor_bytes!(vec![0x01]) < cbor_bytes!(vec![0xFF]));
671
        assert!(cbor_bytes!(vec![0xFF]) < cbor_bytes!(vec![0x00, 0x00]));
672
        assert!(cbor_bytes!(vec![0x00, 0x00]) < cbor_text!(""));
673
        assert!(cbor_text!("") < cbor_text!("a"));
674
        assert!(cbor_text!("a") < cbor_text!("b"));
675
        assert!(cbor_text!("b") < cbor_text!("aa"));
676
        assert!(cbor_text!("aa") < cbor_array![]);
677
        assert!(cbor_array![] < cbor_array![0]);
678
        assert!(cbor_array![0] < cbor_array![-1]);
679
        assert!(cbor_array![1] < cbor_array![b""]);
680
        assert!(cbor_array![b""] < cbor_array![""]);
681
        assert!(cbor_array![""] < cbor_array![cbor_array![]]);
682
        assert!(cbor_array![cbor_array![]] < cbor_array![cbor_map! {}]);
683
        assert!(cbor_array![cbor_map! {}] < cbor_array![false]);
684
        assert!(cbor_array![false] < cbor_array![0, 0]);
685
        assert!(cbor_array![0, 1] < cbor_array![0, 2]);
686
        assert!(cbor_array![0, 0] < cbor_map! {});
687
        assert!(cbor_map! {} < cbor_map! {0 => 0});
688
        assert!(cbor_map! {0 => 0} < cbor_map! {0 => 1});
689
        assert!(cbor_map! {0 => 1} < cbor_map! {1 => 0});
690
        assert!(cbor_map! {1 => 0} < cbor_map! {-1 => 0});
691
        assert!(cbor_map! {-1 => 0} < cbor_map! {b"" => 0});
692
        assert!(cbor_map! {b"" => 0} < cbor_map! {"" => 0});
693
        assert!(cbor_map! {"" => 0} < cbor_map! {cbor_array![] => 0});
694
        assert!(cbor_map! {cbor_array![] => 0} < cbor_map! {cbor_map!{} => 0});
695
        assert!(cbor_map! {cbor_map!{} => 0} < cbor_map! {false => 0});
696
        assert!(cbor_map! {false => 0} < cbor_map! {0 => 0, 1 => 0});
697
        assert!(cbor_map! {0 => 0, 1 => 1} < cbor_map! {0 => 0, 1 => 2});
698
        assert!(cbor_map! {0 => 0} < cbor_tagged!(2, cbor_int!(0)));
699
        assert!(cbor_map! {0 => 0, 1 => 0} < cbor_bool!(false));
700
        assert!(cbor_bool!(false) < cbor_bool!(true));
701
        assert!(cbor_bool!(true) < cbor_null!());
702
        assert!(cbor_null!() < cbor_undefined!());
703
        assert!(cbor_tagged!(1, cbor_text!("s")) < cbor_tagged!(2, cbor_int!(0)));
704
        assert!(cbor_tagged!(1, cbor_unsigned!(0)) < cbor_tagged!(1, cbor_unsigned!(1)));
705
        assert!(cbor_int!(1) < cbor_int!(-1));
706
        assert!(cbor_int!(1) < cbor_bytes!(vec![0x00]));
707
        assert!(cbor_int!(1) < cbor_text!("s"));
708
        assert!(cbor_int!(1) < cbor_array![]);
709
        assert!(cbor_int!(1) < cbor_map! {});
710
        assert!(cbor_int!(1) < cbor_tagged!(1, cbor_text!("s")));
711
        assert!(cbor_int!(1) < cbor_bool!(false));
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_bytes!(vec![0x00]) < cbor_text!("s"));
719
        assert!(cbor_bytes!(vec![0x00]) < cbor_array![]);
720
        assert!(cbor_bytes!(vec![0x00]) < cbor_map! {});
721
        assert!(cbor_bytes!(vec![0x00]) < cbor_tagged!(1, cbor_text!("s")));
722
        assert!(cbor_bytes!(vec![0x00]) < cbor_bool!(false));
723
        assert!(cbor_text!("s") < cbor_array![]);
724
        assert!(cbor_text!("s") < cbor_map! {});
725
        assert!(cbor_text!("s") < cbor_tagged!(1, cbor_text!("s")));
726
        assert!(cbor_text!("s") < cbor_bool!(false));
727
        assert!(cbor_array![] < cbor_map!(0 => 1));
728
        assert!(cbor_array![] < cbor_tagged!(2, cbor_int!(0)));
729
        assert!(cbor_array![] < cbor_bool!(false));
730
        assert!(cbor_tagged!(1, cbor_text!("s")) < cbor_bool!(false));
731
    }
732
}