1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
//! Ordering trait.
use crate::{EncodeValue, Result, Tagged};
use core::cmp::Ordering;
/// DER ordering trait.
///
/// Compares the ordering of two values based on their ASN.1 DER
/// serializations.
///
/// This is used by the DER encoding for `SET OF` in order to establish an
/// ordering for the elements of sets.
pub trait DerOrd {
/// Return an [`Ordering`] between `self` and `other` when serialized as
/// ASN.1 DER.
fn der_cmp(&self, other: &Self) -> Result<Ordering>;
}
/// DER value ordering trait.
///
/// Compares the ordering of the value portion of TLV-encoded DER productions.
pub trait ValueOrd {
/// Return an [`Ordering`] between value portion of TLV-encoded `self` and
/// `other` when serialized as ASN.1 DER.
fn value_cmp(&self, other: &Self) -> Result<Ordering>;
}
impl<T> DerOrd for T
where
T: EncodeValue + ValueOrd + Tagged,
{
fn der_cmp(&self, other: &Self) -> Result<Ordering> {
match self.header()?.der_cmp(&other.header()?)? {
Ordering::Equal => self.value_cmp(other),
ordering => Ok(ordering),
}
}
}
/// Marker trait for types whose `Ord` impl can be used as `ValueOrd`.
///
/// This means the `Ord` impl will sort values in the same order as their DER
/// encodings.
pub trait OrdIsValueOrd: Ord {}
impl<T> ValueOrd for T
where
T: OrdIsValueOrd,
{
fn value_cmp(&self, other: &Self) -> Result<Ordering> {
Ok(self.cmp(other))
}
}