/rust/registry/src/index.crates.io-6f17d22bba15001f/der-0.7.10/src/ord.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Ordering trait. |
2 | | |
3 | | use crate::{EncodeValue, Result, Tagged}; |
4 | | use core::{cmp::Ordering, marker::PhantomData}; |
5 | | |
6 | | /// DER ordering trait. |
7 | | /// |
8 | | /// Compares the ordering of two values based on their ASN.1 DER |
9 | | /// serializations. |
10 | | /// |
11 | | /// This is used by the DER encoding for `SET OF` in order to establish an |
12 | | /// ordering for the elements of sets. |
13 | | pub trait DerOrd { |
14 | | /// Return an [`Ordering`] between `self` and `other` when serialized as |
15 | | /// ASN.1 DER. |
16 | | fn der_cmp(&self, other: &Self) -> Result<Ordering>; |
17 | | } |
18 | | |
19 | | /// DER value ordering trait. |
20 | | /// |
21 | | /// Compares the ordering of the value portion of TLV-encoded DER productions. |
22 | | pub trait ValueOrd { |
23 | | /// Return an [`Ordering`] between value portion of TLV-encoded `self` and |
24 | | /// `other` when serialized as ASN.1 DER. |
25 | | fn value_cmp(&self, other: &Self) -> Result<Ordering>; |
26 | | } |
27 | | |
28 | | impl<T> DerOrd for T |
29 | | where |
30 | | T: EncodeValue + ValueOrd + Tagged, |
31 | | { |
32 | 0 | fn der_cmp(&self, other: &Self) -> Result<Ordering> { |
33 | 0 | match self.header()?.der_cmp(&other.header()?)? { |
34 | 0 | Ordering::Equal => self.value_cmp(other), |
35 | 0 | ordering => Ok(ordering), |
36 | | } |
37 | 0 | } Unexecuted instantiation: <u8 as der::ord::DerOrd>::der_cmp Unexecuted instantiation: <alloc::vec::Vec<u8> as der::ord::DerOrd>::der_cmp |
38 | | } |
39 | | |
40 | | /// Marker trait for types whose `Ord` impl can be used as `ValueOrd`. |
41 | | /// |
42 | | /// This means the `Ord` impl will sort values in the same order as their DER |
43 | | /// encodings. |
44 | | pub trait OrdIsValueOrd: Ord {} |
45 | | |
46 | | impl<T> ValueOrd for T |
47 | | where |
48 | | T: OrdIsValueOrd, |
49 | | { |
50 | 0 | fn value_cmp(&self, other: &Self) -> Result<Ordering> { |
51 | 0 | Ok(self.cmp(other)) |
52 | 0 | } |
53 | | } |
54 | | |
55 | | /// Compare the order of two iterators using [`DerCmp`] on the values. |
56 | 0 | pub(crate) fn iter_cmp<'a, I, T: 'a>(a: I, b: I) -> Result<Ordering> |
57 | 0 | where |
58 | 0 | I: Iterator<Item = &'a T> + ExactSizeIterator, |
59 | 0 | T: DerOrd, |
60 | 0 | { |
61 | 0 | let length_ord = a.len().cmp(&b.len()); |
62 | | |
63 | 0 | for (value1, value2) in a.zip(b) { |
64 | 0 | match value1.der_cmp(value2)? { |
65 | 0 | Ordering::Equal => (), |
66 | 0 | other => return Ok(other), |
67 | | } |
68 | | } |
69 | | |
70 | 0 | Ok(length_ord) |
71 | 0 | } |
72 | | |
73 | | /// Provide a no-op implementation for PhantomData |
74 | | impl<T> ValueOrd for PhantomData<T> { |
75 | 0 | fn value_cmp(&self, _other: &Self) -> Result<Ordering> { |
76 | 0 | Ok(Ordering::Equal) |
77 | 0 | } |
78 | | } |
79 | | |
80 | | /// Provide a no-op implementation for PhantomData |
81 | | impl<T> DerOrd for PhantomData<T> { |
82 | 0 | fn der_cmp(&self, _other: &Self) -> Result<Ordering> { |
83 | 0 | Ok(Ordering::Equal) |
84 | 0 | } |
85 | | } |