Skip to content

Commit

Permalink
Merge pull request #1672 from CosmWasm/add-forward_ref_partial_eq
Browse files Browse the repository at this point in the history
Create forward_ref_partial_eq to implement mixed reference PartialEq
  • Loading branch information
webmaster128 authored May 2, 2023
2 parents 96b2475 + 20227d0 commit 3651064
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 90 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ and this project adheres to

## [Unreleased]

### Added

- cosmwasm-std: Implement `PartialEq` for `Addr == &Addr` and `&Addr == Addr` as
well as `Event == &Event` and `&Event == Event` ([#1672]).

[#1672]: https://github.com/CosmWasm/cosmwasm/pull/1672

### Deprecated

- cosmwasm-std: The PartialEq implementations between `Addr` and `&str`/`String`
Expand Down
18 changes: 17 additions & 1 deletion packages/std/src/addresses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::fmt;
use std::ops::Deref;
use thiserror::Error;

use crate::{binary::Binary, HexBinary};
use crate::{binary::Binary, forward_ref_partial_eq, HexBinary};

/// A human readable address.
///
Expand All @@ -32,6 +32,8 @@ use crate::{binary::Binary, HexBinary};
)]
pub struct Addr(String);

forward_ref_partial_eq!(Addr, Addr);

impl Addr {
/// Creates a new `Addr` instance from the given input without checking the validity
/// of the input. Since `Addr` must always contain valid addresses, the caller is
Expand Down Expand Up @@ -454,6 +456,20 @@ mod tests {
assert_eq!(String::from("cos934gh9034hg04g0h134"), addr);
}

#[test]
fn addr_implements_partial_eq_addr_ref() {
let addr = Addr::unchecked("cos934gh9034hg04g0h134");
let addr_ref = &addr;
let addr_ref2 = &addr;

// `Addr == &Addr`
assert_eq!(addr, addr_ref);
// `&Addr == Addr`
assert_eq!(addr_ref, addr);
// `&Addr == &Addr`
assert_eq!(addr_ref, addr_ref2);
}

#[test]
fn addr_implements_into_string() {
// owned Addr
Expand Down
25 changes: 25 additions & 0 deletions packages/std/src/forward_ref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/// Given an implementation of `T == U`, implements:
/// - `&T == U`
/// - `T == &U`
///
/// We don't need to add `&T == &U` here because this is implemented automatically.
#[macro_export]
macro_rules! forward_ref_partial_eq {
($t:ty, $u:ty) => {
// `&T == U`
impl<'a> PartialEq<$u> for &'a $t {
#[inline]
fn eq(&self, rhs: &$u) -> bool {
**self == *rhs // Implement via T == U
}
}

// `T == &U`
impl PartialEq<&$u> for $t {
#[inline]
fn eq(&self, rhs: &&$u) -> bool {
*self == **rhs // Implement via T == U
}
}
};
}
1 change: 1 addition & 0 deletions packages/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod coin;
mod conversion;
mod deps;
mod errors;
mod forward_ref;
mod hex_binary;
mod ibc;
mod import_helpers;
Expand Down
15 changes: 3 additions & 12 deletions packages/std/src/math/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::errors::{
CheckedFromRatioError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
OverflowOperation, RoundUpOverflowError, StdError,
};
use crate::forward_ref_partial_eq;

use super::Fraction;
use super::Isqrt;
Expand All @@ -22,6 +23,8 @@ use super::{Uint128, Uint256};
#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
pub struct Decimal(#[schemars(with = "String")] Uint128);

forward_ref_partial_eq!(Decimal, Decimal);

#[derive(Error, Debug, PartialEq, Eq)]
#[error("Decimal range exceeded")]
pub struct DecimalRangeExceeded;
Expand Down Expand Up @@ -705,18 +708,6 @@ impl<'de> de::Visitor<'de> for DecimalVisitor {
}
}

impl PartialEq<&Decimal> for Decimal {
fn eq(&self, rhs: &&Decimal) -> bool {
self == *rhs
}
}

impl PartialEq<Decimal> for &Decimal {
fn eq(&self, rhs: &Decimal) -> bool {
*self == rhs
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
16 changes: 3 additions & 13 deletions packages/std/src/math/decimal256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::errors::{
CheckedFromRatioError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
OverflowOperation, RoundUpOverflowError, StdError,
};
use crate::{Decimal, Uint512};
use crate::{forward_ref_partial_eq, Decimal, Uint512};

use super::Fraction;
use super::Isqrt;
Expand All @@ -25,6 +25,8 @@ use super::Uint256;
#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
pub struct Decimal256(#[schemars(with = "String")] Uint256);

forward_ref_partial_eq!(Decimal256, Decimal256);

#[derive(Error, Debug, PartialEq, Eq)]
#[error("Decimal256 range exceeded")]
pub struct Decimal256RangeExceeded;
Expand Down Expand Up @@ -730,18 +732,6 @@ impl<'de> de::Visitor<'de> for Decimal256Visitor {
}
}

impl PartialEq<&Decimal256> for Decimal256 {
fn eq(&self, rhs: &&Decimal256) -> bool {
self == *rhs
}
}

impl PartialEq<Decimal256> for &Decimal256 {
fn eq(&self, rhs: &Decimal256) -> bool {
*self == rhs
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
18 changes: 5 additions & 13 deletions packages/std/src/math/uint128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ use crate::errors::{
CheckedMultiplyFractionError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
OverflowOperation, StdError,
};
use crate::{impl_mul_fraction, ConversionOverflowError, Fraction, Uint256, Uint64};
use crate::{
forward_ref_partial_eq, impl_mul_fraction, ConversionOverflowError, Fraction, Uint256, Uint64,
};

/// A thin wrapper around u128 that is using strings for JSON encoding/decoding,
/// such that the full u128 range can be used for clients that convert JSON numbers to floats,
Expand All @@ -36,6 +38,8 @@ use crate::{impl_mul_fraction, ConversionOverflowError, Fraction, Uint256, Uint6
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
pub struct Uint128(#[schemars(with = "String")] u128);

forward_ref_partial_eq!(Uint128, Uint128);

impl Uint128 {
pub const MAX: Self = Self(u128::MAX);
pub const MIN: Self = Self(u128::MIN);
Expand Down Expand Up @@ -527,18 +531,6 @@ where
}
}

impl PartialEq<&Uint128> for Uint128 {
fn eq(&self, rhs: &&Uint128) -> bool {
self == *rhs
}
}

impl PartialEq<Uint128> for &Uint128 {
fn eq(&self, rhs: &Uint128) -> bool {
*self == rhs
}
}

#[cfg(test)]
mod tests {
use crate::errors::CheckedMultiplyFractionError::{ConversionOverflow, DivideByZero};
Expand Down
16 changes: 3 additions & 13 deletions packages/std/src/math/uint256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::errors::{
CheckedMultiplyFractionError, CheckedMultiplyRatioError, ConversionOverflowError,
DivideByZeroError, OverflowError, OverflowOperation, StdError,
};
use crate::{impl_mul_fraction, Fraction, Uint128, Uint512, Uint64};
use crate::{forward_ref_partial_eq, impl_mul_fraction, Fraction, Uint128, Uint512, Uint64};

/// This module is purely a workaround that lets us ignore lints for all the code
/// the `construct_uint!` macro generates.
Expand Down Expand Up @@ -50,6 +50,8 @@ use uints::U256;
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
pub struct Uint256(#[schemars(with = "String")] U256);

forward_ref_partial_eq!(Uint256, Uint256);

impl Uint256 {
pub const MAX: Uint256 = Uint256(U256::MAX);
pub const MIN: Uint256 = Uint256(U256::zero());
Expand Down Expand Up @@ -653,18 +655,6 @@ where
}
}

impl PartialEq<&Uint256> for Uint256 {
fn eq(&self, rhs: &&Uint256) -> bool {
self == *rhs
}
}

impl PartialEq<Uint256> for &Uint256 {
fn eq(&self, rhs: &Uint256) -> bool {
*self == rhs
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
16 changes: 3 additions & 13 deletions packages/std/src/math/uint512.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::str::FromStr;
use crate::errors::{
ConversionOverflowError, DivideByZeroError, OverflowError, OverflowOperation, StdError,
};
use crate::{Uint128, Uint256, Uint64};
use crate::{forward_ref_partial_eq, Uint128, Uint256, Uint64};

/// This module is purely a workaround that lets us ignore lints for all the code
/// the `construct_uint!` macro generates.
Expand Down Expand Up @@ -52,6 +52,8 @@ use uints::U512;
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
pub struct Uint512(#[schemars(with = "String")] U512);

forward_ref_partial_eq!(Uint512, Uint512);

impl Uint512 {
pub const MAX: Uint512 = Uint512(U512::MAX);
pub const MIN: Uint512 = Uint512(U512::zero());
Expand Down Expand Up @@ -606,18 +608,6 @@ where
}
}

impl PartialEq<&Uint512> for Uint512 {
fn eq(&self, rhs: &&Uint512) -> bool {
self == *rhs
}
}

impl PartialEq<Uint512> for &Uint512 {
fn eq(&self, rhs: &Uint512) -> bool {
*self == rhs
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
16 changes: 3 additions & 13 deletions packages/std/src/math/uint64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::errors::{
CheckedMultiplyFractionError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
OverflowOperation, StdError,
};
use crate::{impl_mul_fraction, Fraction, Uint128};
use crate::{forward_ref_partial_eq, impl_mul_fraction, Fraction, Uint128};

/// A thin wrapper around u64 that is using strings for JSON encoding/decoding,
/// such that the full u64 range can be used for clients that convert JSON numbers to floats,
Expand All @@ -31,6 +31,8 @@ use crate::{impl_mul_fraction, Fraction, Uint128};
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
pub struct Uint64(#[schemars(with = "String")] u64);

forward_ref_partial_eq!(Uint64, Uint64);

impl Uint64 {
pub const MAX: Self = Self(u64::MAX);
pub const MIN: Self = Self(u64::MIN);
Expand Down Expand Up @@ -480,18 +482,6 @@ where
}
}

impl PartialEq<&Uint64> for Uint64 {
fn eq(&self, rhs: &&Uint64) -> bool {
self == *rhs
}
}

impl PartialEq<Uint64> for &Uint64 {
fn eq(&self, rhs: &Uint64) -> bool {
*self == rhs
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
18 changes: 6 additions & 12 deletions packages/std/src/results/events.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use crate::forward_ref_partial_eq;

/// A full [*Cosmos SDK* event].
///
/// This version uses string attributes (similar to [*Cosmos SDK* StringEvent]),
Expand All @@ -23,6 +25,8 @@ pub struct Event {
pub attributes: Vec<Attribute>,
}

forward_ref_partial_eq!(Event, Event);

impl Event {
/// Create a new event with the given type and an empty list of attributes.
pub fn new(ty: impl Into<String>) -> Self {
Expand Down Expand Up @@ -61,6 +65,8 @@ pub struct Attribute {
pub value: String,
}

forward_ref_partial_eq!(Attribute, Attribute);

impl Attribute {
/// Creates a new Attribute. `attr` is just an alias for this.
pub fn new(key: impl Into<String>, value: impl Into<String>) -> Self {
Expand Down Expand Up @@ -111,18 +117,6 @@ impl<K: AsRef<str>, V: AsRef<str>> PartialEq<&Attribute> for (K, V) {
}
}

impl PartialEq<Attribute> for &Attribute {
fn eq(&self, rhs: &Attribute) -> bool {
*self == rhs
}
}

impl PartialEq<&Attribute> for Attribute {
fn eq(&self, rhs: &&Attribute) -> bool {
self == *rhs
}
}

/// Creates a new Attribute. `Attribute::new` is an alias for this.
#[inline]
pub fn attr(key: impl Into<String>, value: impl Into<String>) -> Attribute {
Expand Down

0 comments on commit 3651064

Please sign in to comment.