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