mz_ore/treat_as_equal.rs
1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License in the LICENSE file at the
6// root of this repository, or online at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! A newtype for values that should be ignored when comparing two values for equality.
17
18use derivative::Derivative;
19use serde::{Deserialize, Deserializer, Serialize};
20use std::cmp::Ordering;
21use std::hash::{Hash, Hasher};
22
23/// Behaves like `T`, but has trivial `Hash`, `Eq`, `MzReflect`, and `Ord`
24/// implementations. Does not appear in `Debug` output, but _is_ serialized.
25#[derive(Clone, Default, Derivative)]
26#[derivative(Debug = "transparent")]
27pub struct TreatAsEqual<T>(pub T);
28
29impl<T> Hash for TreatAsEqual<T> {
30 fn hash<H: Hasher>(&self, _state: &mut H) {}
31}
32
33impl<T> Eq for TreatAsEqual<T> {}
34
35impl<T> PartialEq for TreatAsEqual<T> {
36 fn eq(&self, _other: &Self) -> bool {
37 true
38 }
39}
40
41impl<T> PartialOrd for TreatAsEqual<T> {
42 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
43 Some(self.cmp(other))
44 }
45}
46
47impl<T> Ord for TreatAsEqual<T> {
48 fn cmp(&self, _other: &Self) -> Ordering {
49 Ordering::Equal
50 }
51}
52
53// We define the serializer to not bother recording the `TreatAsEqual` newtype
54// constructor to reduce noise.
55impl<T: Serialize> Serialize for TreatAsEqual<T> {
56 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
57 self.0.serialize(serializer)
58 }
59}
60
61impl<'de, T: Deserialize<'de>> Deserialize<'de> for TreatAsEqual<T> {
62 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
63 Ok(TreatAsEqual(T::deserialize(deserializer)?))
64 }
65}