1use crate::{EncodeValue, Result, Tagged};
4use core::{cmp::Ordering, marker::PhantomData};
5
6pub trait DerOrd {
14 fn der_cmp(&self, other: &Self) -> Result<Ordering>;
20}
21
22pub trait ValueOrd {
26 fn value_cmp(&self, other: &Self) -> Result<Ordering>;
32}
33
34impl<T> DerOrd for T
35where
36 T: EncodeValue + ValueOrd + Tagged,
37{
38 fn der_cmp(&self, other: &Self) -> Result<Ordering> {
39 match (self.header(), other.header()) {
41 (Ok(this), Ok(that)) => {
42 let cmp_result = this.der_cmp(&that);
43 match cmp_result {
44 Err(err) => Err(err),
45 Ok(Ordering::Equal) => self.value_cmp(other),
46 Ok(ordering) => Ok(ordering),
47 }
48 }
49 (Err(err), _) => Err(err),
50 (_, Err(err)) => Err(err),
51 }
52 }
53}
54
55pub trait OrdIsValueOrd: Ord {}
60
61impl<T> ValueOrd for T
62where
63 T: OrdIsValueOrd,
64{
65 fn value_cmp(&self, other: &Self) -> Result<Ordering> {
66 Ok(self.cmp(other))
67 }
68}
69
70pub(crate) fn iter_cmp<'a, I, T>(a: I, b: I) -> Result<Ordering>
72where
73 I: Iterator<Item = &'a T> + ExactSizeIterator,
74 T: 'a + DerOrd,
75{
76 let length_ord = a.len().cmp(&b.len());
77
78 for (value1, value2) in a.zip(b) {
79 match value1.der_cmp(value2)? {
80 Ordering::Equal => (),
81 other => return Ok(other),
82 }
83 }
84
85 Ok(length_ord)
86}
87
88#[cfg(any(feature = "alloc", feature = "heapless"))]
89pub(crate) fn iter_cmp_owned<'a, I, T>(a: I, b: I) -> Result<Ordering>
91where
92 I: Iterator<Item = T> + ExactSizeIterator,
93 T: 'a + DerOrd,
94{
95 let length_ord = a.len().cmp(&b.len());
96
97 for (value1, value2) in a.zip(b) {
98 match value1.der_cmp(&value2)? {
99 Ordering::Equal => (),
100 other => return Ok(other),
101 }
102 }
103
104 Ok(length_ord)
105}
106
107impl<T> ValueOrd for PhantomData<T> {
109 fn value_cmp(&self, _other: &Self) -> Result<Ordering> {
110 Ok(Ordering::Equal)
111 }
112}
113
114impl<T> DerOrd for PhantomData<T> {
116 fn der_cmp(&self, _other: &Self) -> Result<Ordering> {
117 Ok(Ordering::Equal)
118 }
119}