json_syntax/
unordered.rs

1use core::hash::{Hash, Hasher};
2
3use locspan::Meta;
4
5/// Wrapper to view a value without considering the order of
6/// the objects entries.
7#[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}