1use core::hash::{Hash, Hasher};
2
3use locspan::Meta;
4
5#[derive(Debug)]
8#[repr(transparent)]
9pub struct Unordered<T: ?Sized>(pub T);
10
11pub trait BorrowUnordered {
12 fn as_unordered(&self) -> &Unordered<Self>;
13}
14
15impl<T> BorrowUnordered for T {
16 fn as_unordered(&self) -> &Unordered<Self> {
17 unsafe { core::mem::transmute(self) }
18 }
19}
20
21pub trait UnorderedPartialEq {
22 fn unordered_eq(&self, other: &Self) -> bool;
23}
24
25impl<T: UnorderedPartialEq, M: PartialEq> UnorderedPartialEq for Meta<T, M> {
26 fn unordered_eq(&self, other: &Self) -> bool {
27 self.metadata() == other.metadata() && self.value().unordered_eq(other.value())
28 }
29}
30
31impl<T: UnorderedPartialEq> UnorderedPartialEq for Vec<T> {
32 fn unordered_eq(&self, other: &Self) -> bool {
33 self.len() == other.len() && self.iter().zip(other).all(|(a, b)| a.unordered_eq(b))
34 }
35}
36
37impl<T: UnorderedPartialEq> PartialEq for Unordered<T> {
38 fn eq(&self, other: &Self) -> bool {
39 self.0.unordered_eq(&other.0)
40 }
41}
42
43pub trait UnorderedEq: UnorderedPartialEq {}
44
45impl<T: UnorderedEq, M: Eq> UnorderedEq for Meta<T, M> {}
46
47impl<T: UnorderedEq> Eq for Unordered<T> {}
48
49pub trait UnorderedHash {
50 fn unordered_hash<H: Hasher>(&self, state: &mut H);
51}
52
53impl<T: UnorderedHash> Hash for Unordered<T> {
54 fn hash<H: Hasher>(&self, state: &mut H) {
55 self.0.unordered_hash(state)
56 }
57}