Coverage Report

Created: 2025-07-14 07:05

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