Impl `PartialEq` between `Witness` and containers
Since `Witness` is semantically equivalent to `&[&[u8]]` they should also be comparable. However we only had the impl to compare `Witness` with itself. Being able to compare `Witness` with other containers is particularly needed in tests.
This commit is contained in:
parent
587a66da47
commit
c8078360d2
|
@ -14,7 +14,7 @@ use internals::compact_size;
|
||||||
use internals::wrap_debug::WrapDebug;
|
use internals::wrap_debug::WrapDebug;
|
||||||
use internals::slice::SliceExt;
|
use internals::slice::SliceExt;
|
||||||
|
|
||||||
use crate::prelude::Vec;
|
use crate::prelude::{Box, Vec};
|
||||||
|
|
||||||
/// The Witness is the data used to unlock bitcoin since the [SegWit upgrade].
|
/// The Witness is the data used to unlock bitcoin since the [SegWit upgrade].
|
||||||
///
|
///
|
||||||
|
@ -238,6 +238,109 @@ fn decode_cursor(bytes: &[u8], start_of_indices: usize, index: usize) -> Option<
|
||||||
bytes.get_array::<4>(start).map(|index_bytes| u32::from_ne_bytes(*index_bytes) as usize)
|
bytes.get_array::<4>(start).map(|index_bytes| u32::from_ne_bytes(*index_bytes) as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: we use `Borrow` in the following `PartialEq` impls specifically because of its additional
|
||||||
|
// constraints on equality semantics.
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<[T]> for Witness {
|
||||||
|
fn eq(&self, rhs: &[T]) -> bool {
|
||||||
|
if self.len() != rhs.len() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self.iter().zip(rhs).all(|(left, right)| left == right.borrow())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<&[T]> for Witness {
|
||||||
|
fn eq(&self, rhs: &&[T]) -> bool {
|
||||||
|
*self == **rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<Witness> for [T] {
|
||||||
|
fn eq(&self, rhs: &Witness) -> bool {
|
||||||
|
*rhs == *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<Witness> for &[T] {
|
||||||
|
fn eq(&self, rhs: &Witness) -> bool {
|
||||||
|
*rhs == **self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize, T: core::borrow::Borrow<[u8]>> PartialEq<[T; N]> for Witness {
|
||||||
|
fn eq(&self, rhs: &[T; N]) -> bool {
|
||||||
|
*self == *rhs.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize, T: core::borrow::Borrow<[u8]>> PartialEq<&[T; N]> for Witness {
|
||||||
|
fn eq(&self, rhs: &&[T; N]) -> bool {
|
||||||
|
*self == *rhs.as_slice()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize, T: core::borrow::Borrow<[u8]>> PartialEq<Witness> for [T; N] {
|
||||||
|
fn eq(&self, rhs: &Witness) -> bool {
|
||||||
|
*rhs == *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const N: usize, T: core::borrow::Borrow<[u8]>> PartialEq<Witness> for &[T; N] {
|
||||||
|
fn eq(&self, rhs: &Witness) -> bool {
|
||||||
|
*rhs == **self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<Vec<T>> for Witness {
|
||||||
|
fn eq(&self, rhs: &Vec<T>) -> bool {
|
||||||
|
*self == **rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<Witness> for Vec<T> {
|
||||||
|
fn eq(&self, rhs: &Witness) -> bool {
|
||||||
|
*rhs == *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<Box<[T]>> for Witness {
|
||||||
|
fn eq(&self, rhs: &Box<[T]>) -> bool {
|
||||||
|
*self == **rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<Witness> for Box<[T]> {
|
||||||
|
fn eq(&self, rhs: &Witness) -> bool {
|
||||||
|
*rhs == *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<alloc::rc::Rc<[T]>> for Witness {
|
||||||
|
fn eq(&self, rhs: &alloc::rc::Rc<[T]>) -> bool {
|
||||||
|
*self == **rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<Witness> for alloc::rc::Rc<[T]> {
|
||||||
|
fn eq(&self, rhs: &Witness) -> bool {
|
||||||
|
*rhs == *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<alloc::sync::Arc<[T]>> for Witness {
|
||||||
|
fn eq(&self, rhs: &alloc::sync::Arc<[T]>) -> bool {
|
||||||
|
*self == **rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_has_atomic = "ptr")]
|
||||||
|
impl<T: core::borrow::Borrow<[u8]>> PartialEq<Witness> for alloc::sync::Arc<[T]> {
|
||||||
|
fn eq(&self, rhs: &Witness) -> bool {
|
||||||
|
*rhs == *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Debug implementation that displays the witness as a structured output containing:
|
/// Debug implementation that displays the witness as a structured output containing:
|
||||||
/// - Number of witness elements
|
/// - Number of witness elements
|
||||||
/// - Total bytes across all elements
|
/// - Total bytes across all elements
|
||||||
|
@ -643,6 +746,27 @@ mod test {
|
||||||
assert!(expected.is_empty());
|
assert!(expected.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn partial_eq() {
|
||||||
|
const EMPTY_BYTES: &[u8] = &[];
|
||||||
|
assert_eq!(Vec::<&[u8]>::new(), Witness::new());
|
||||||
|
macro_rules! ck {
|
||||||
|
($container:expr) => {
|
||||||
|
{
|
||||||
|
let container = $container;
|
||||||
|
let witness = Witness::from(Clone::clone(&container));
|
||||||
|
assert_eq!(witness, container, stringify!($container));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ck!([EMPTY_BYTES]);
|
||||||
|
ck!([EMPTY_BYTES, EMPTY_BYTES]);
|
||||||
|
ck!([[42]]);
|
||||||
|
ck!([[42, 21]]);
|
||||||
|
ck!([&[42], EMPTY_BYTES]);
|
||||||
|
ck!([[42u8], [21]]);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
fn serde_bincode_backward_compatibility() {
|
fn serde_bincode_backward_compatibility() {
|
||||||
|
|
Loading…
Reference in New Issue