diff --git a/src/p384/identifier.rs b/src/p384/identifier.rs index 5932eb3..f0f4e7f 100644 --- a/src/p384/identifier.rs +++ b/src/p384/identifier.rs @@ -13,35 +13,44 @@ pub enum PeerIdentifier { Address(Address), Short(ShortAddress), } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Copy, Hash)] pub enum PeerIdentifierRef<'a> { Identity(&'a Identity), Address(&'a Address), Short(ShortAddress), } -impl PeerIdentifier { - pub fn matches(&self, identity: &Identity) -> bool { +#[derive(Debug, Clone, Copy, Hash)] +pub enum AnyAddress { + Address(Address), + Short(ShortAddress), +} + +impl<'a> PeerIdentifierRef<'a> { + pub fn matches(self, identity: &Identity) -> bool { + use PeerIdentifierRef::*; match self { - PeerIdentifier::Identity(id) => id.eq(identity), - PeerIdentifier::Address(id) => identity.address.eq(id), - PeerIdentifier::Short(id) => identity.address.prefix().eq(id), + Identity(id) => (*id).eq(identity), + Address(id) => identity.address.eq(id), + Short(id) => identity.address.prefix().eq(&id), } } pub fn prefix(&self) -> &ShortAddress { + use PeerIdentifierRef::*; match self { - PeerIdentifier::Identity(id) => id.address.prefix(), - PeerIdentifier::Address(id) => id.prefix(), - PeerIdentifier::Short(id) => id, + Identity(id) => id.address.prefix(), + Address(id) => id.prefix(), + Short(id) => id, } } - pub fn address(&self) -> AnyAddress { + pub fn address(self) -> AnyAddress { + use PeerIdentifierRef::*; match self { - PeerIdentifier::Identity(id) => id.address.into(), - PeerIdentifier::Address(id) => id.into(), - PeerIdentifier::Short(id) => id.into(), + Identity(id) => id.address.into(), + Address(id) => (*id).into(), + Short(id) => id.into(), } } @@ -51,9 +60,9 @@ impl PeerIdentifier { /// This function will debug panic if `self` and `other` are not identifiers for the same peer. /// The caller must check for equality before calling this function. /// TODO: make this function take into account identity lifetime. - pub fn upgrade_check(&self, other: &Self) -> bool { + pub fn upgrade_check(self, other: Self) -> bool { debug_assert_eq!(self, other); - use PeerIdentifier::*; + use PeerIdentifierRef::*; match (self, other) { (Identity(_), _) => false, (_, Identity(_)) => true, @@ -62,51 +71,39 @@ impl PeerIdentifier { } } } -/// Does not preserve transitivity. -impl std::cmp::PartialEq for PeerIdentifier { - fn eq(&self, other: &Self) -> bool { + +impl PeerIdentifier { + pub fn matches(&self, identity: &Identity) -> bool { + let r: PeerIdentifierRef = self.into(); + r.matches(identity) + } + + pub fn prefix(&self) -> &ShortAddress { use PeerIdentifier::*; - match (self, other) { - (Identity(identity), id) | (id, Identity(identity)) => id.matches(identity), - (Address(addr0), Address(addr1)) => addr0.eq(addr1), - (Address(addr0), Short(addr1)) => addr0.prefix().eq(addr1), - (Short(addr0), Address(addr1)) => addr0.eq(addr1.prefix()), - (Short(addr0), Short(addr1)) => addr0.eq(addr1), + match self { + Identity(id) => id.address.prefix(), + Address(id) => id.prefix(), + Short(id) => id, } } -} -impl From
for PeerIdentifier { - fn from(value: Address) -> Self { - Self::Address(value) + + pub fn address(&self) -> AnyAddress { + let r: PeerIdentifierRef = self.into(); + r.address() } -} -impl From for PeerIdentifier { - fn from(value: ShortAddress) -> Self { - Self::Short(value) - } -} -impl From<&Address> for PeerIdentifier { - fn from(value: &Address) -> Self { - Self::Address(*value) - } -} -impl From<&ShortAddress> for PeerIdentifier { - fn from(value: &ShortAddress) -> Self { - Self::Short(*value) + + /// Returns `true` if `other` contains the most complete version of the identity between + /// `self` and `other`. + /// Otherwise returns `false`. + /// This function will debug panic if `self` and `other` are not identifiers for the same peer. + /// The caller must check for equality before calling this function. + /// TODO: make this function take into account identity lifetime. + pub fn upgrade_check(&self, other: &Self) -> bool { + let r: PeerIdentifierRef = self.into(); + r.upgrade_check(other.into()) } } -impl From for PeerIdentifier { - fn from(value: Identity) -> Self { - Self::Identity(value) - } -} - -#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy, Hash)] -pub enum AnyAddress { - Address(Address), - Short(ShortAddress), -} impl AnyAddress { pub fn matches(&self, identity: &Identity) -> bool { match self { @@ -136,6 +133,27 @@ impl AnyAddress { } } } + +/// Does not preserve transitivity. +impl<'a> std::cmp::PartialEq for PeerIdentifierRef<'a> { + fn eq(&self, other: &Self) -> bool { + use PeerIdentifierRef::*; + match (self, other) { + (Identity(identity), id) | (id, Identity(identity)) => id.matches(identity), + (Address(addr0), Address(addr1)) => addr0.eq(addr1), + (Address(addr0), Short(addr1)) => addr0.prefix().eq(addr1), + (Short(addr0), Address(addr1)) => addr0.eq(addr1.prefix()), + (Short(addr0), Short(addr1)) => addr0.eq(addr1), + } + } +} +/// Does not preserve transitivity. +impl std::cmp::PartialEq for PeerIdentifier { + fn eq(&self, other: &Self) -> bool { + let r: PeerIdentifierRef = self.into(); + r.eq(&other.into()) + } +} /// Does not preserve transitivity. impl std::cmp::PartialEq for AnyAddress { fn eq(&self, other: &Self) -> bool { @@ -148,6 +166,47 @@ impl std::cmp::PartialEq for AnyAddress { } } } + +impl<'a> From<&'a PeerIdentifier> for PeerIdentifierRef<'a> { + #[inline] + fn from(value: &'a PeerIdentifier) -> Self { + match value { + PeerIdentifier::Identity(v) => PeerIdentifierRef::Identity(v), + PeerIdentifier::Address(v) => PeerIdentifierRef::Address(v), + PeerIdentifier::Short(v) => PeerIdentifierRef::Short(*v), + } + } +} +impl<'a> From> for PeerIdentifier { + #[inline] + fn from(value: PeerIdentifierRef<'a>) -> Self { + match value { + PeerIdentifierRef::Identity(v) => PeerIdentifier::Identity(v.clone()), + PeerIdentifierRef::Address(v) => PeerIdentifier::Address(v.clone()), + PeerIdentifierRef::Short(v) => PeerIdentifier::Short(v), + } + } +} + +impl From for PeerIdentifier { + #[inline] + fn from(value: AnyAddress) -> Self { + match value { + AnyAddress::Address(v) => PeerIdentifier::Address(v), + AnyAddress::Short(v) => PeerIdentifier::Short(v), + } + } +} +impl<'a> From<&'a AnyAddress> for PeerIdentifierRef<'a> { + #[inline] + fn from(value: &'a AnyAddress) -> Self { + match value { + AnyAddress::Address(v) => PeerIdentifierRef::Address(v), + AnyAddress::Short(v) => PeerIdentifierRef::Short(*v), + } + } +} + impl From
for AnyAddress { fn from(value: Address) -> Self { Self::Address(value) @@ -168,3 +227,45 @@ impl From<&ShortAddress> for AnyAddress { Self::Short(*value) } } + +impl From
for PeerIdentifier { + fn from(value: Address) -> Self { + Self::Address(value) + } +} +impl From for PeerIdentifier { + fn from(value: ShortAddress) -> Self { + Self::Short(value) + } +} +impl From<&Address> for PeerIdentifier { + fn from(value: &Address) -> Self { + Self::Address(*value) + } +} +impl From<&ShortAddress> for PeerIdentifier { + fn from(value: &ShortAddress) -> Self { + Self::Short(*value) + } +} +impl From for PeerIdentifier { + fn from(value: Identity) -> Self { + Self::Identity(value) + } +} + +impl<'a> From<&'a Address> for PeerIdentifierRef<'a> { + fn from(value: &'a Address) -> Self { + Self::Address(value) + } +} +impl<'a> From<&ShortAddress> for PeerIdentifierRef<'a> { + fn from(value: &ShortAddress) -> Self { + Self::Short(*value) + } +} +impl<'a> From<&'a Identity> for PeerIdentifierRef<'a> { + fn from(value: &'a Identity) -> Self { + Self::Identity(value) + } +}