/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 | | } |