zcash_address: Use preference ordering for Receivers
This commit is contained in:
parent
7708b27202
commit
b175b9bec9
|
@ -1,3 +1,4 @@
|
|||
use std::cmp;
|
||||
use std::collections::HashSet;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::error::Error;
|
||||
|
@ -36,6 +37,44 @@ pub enum Typecode {
|
|||
Unknown(u8),
|
||||
}
|
||||
|
||||
impl Ord for Typecode {
|
||||
fn cmp(&self, other: &Self) -> cmp::Ordering {
|
||||
match (self, other) {
|
||||
// Trivial equality checks.
|
||||
(Self::Orchard, Self::Orchard)
|
||||
| (Self::Sapling, Self::Sapling)
|
||||
| (Self::P2sh, Self::P2sh)
|
||||
| (Self::P2pkh, Self::P2pkh) => cmp::Ordering::Equal,
|
||||
|
||||
// We don't know for certain the preference order of unknown receivers, but it
|
||||
// is likely that the higher typecode has higher preference. The exact order
|
||||
// doesn't really matter, as unknown receivers have lower preference than
|
||||
// known receivers.
|
||||
(Self::Unknown(a), Self::Unknown(b)) => b.cmp(a),
|
||||
|
||||
// For the remaining cases, we rely on `match` always choosing the first arm
|
||||
// with a matching pattern. Patterns below are listed in priority order:
|
||||
(Self::Orchard, _) => cmp::Ordering::Less,
|
||||
(_, Self::Orchard) => cmp::Ordering::Greater,
|
||||
|
||||
(Self::Sapling, _) => cmp::Ordering::Less,
|
||||
(_, Self::Sapling) => cmp::Ordering::Greater,
|
||||
|
||||
(Self::P2sh, _) => cmp::Ordering::Less,
|
||||
(_, Self::P2sh) => cmp::Ordering::Greater,
|
||||
|
||||
(Self::P2pkh, _) => cmp::Ordering::Less,
|
||||
(_, Self::P2pkh) => cmp::Ordering::Greater,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Typecode {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for Typecode {
|
||||
fn from(typecode: u8) -> Self {
|
||||
match typecode {
|
||||
|
@ -105,7 +144,7 @@ impl Error for ParseError {}
|
|||
///
|
||||
/// > When derived on enums, variants are ordered by their top-to-bottom discriminant
|
||||
/// > order.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) enum Receiver {
|
||||
Orchard([u8; 43]),
|
||||
Sapling(kind::sapling::Data),
|
||||
|
@ -114,6 +153,21 @@ pub(crate) enum Receiver {
|
|||
Unknown { typecode: u8, data: Vec<u8> },
|
||||
}
|
||||
|
||||
impl cmp::Ord for Receiver {
|
||||
fn cmp(&self, other: &Self) -> cmp::Ordering {
|
||||
match self.typecode().cmp(&other.typecode()) {
|
||||
cmp::Ordering::Equal => self.addr().cmp(other.addr()),
|
||||
res => res,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl cmp::PartialOrd for Receiver {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<(u8, &[u8])> for Receiver {
|
||||
type Error = ParseError;
|
||||
|
||||
|
|
Loading…
Reference in New Issue