json_ld_syntax_next/
compare.rs

1use json_syntax::Value;
2
3/// JSON-LD comparison.
4pub trait Compare {
5	fn compare(&self, other: &Self) -> bool;
6}
7
8impl Compare for Value {
9	fn compare(&self, other: &Self) -> bool {
10		match (self, other) {
11			(Self::Null, Self::Null) => true,
12			(Self::Boolean(a), Self::Boolean(b)) => a == b,
13			(Self::Number(a), Self::Number(b)) => a == b,
14			(Self::String(a), Self::String(b)) => a == b,
15			(Self::Array(a), Self::Array(b)) => {
16				if a.len() == b.len() {
17					let mut selected = Vec::new();
18					selected.resize(b.len(), false);
19
20					'next_item: for item in a {
21						for (other, selected) in b.iter().zip(selected.iter_mut()) {
22							if !*selected && item.compare(other) {
23								*selected = true;
24								continue 'next_item;
25							}
26						}
27
28						return false;
29					}
30
31					true
32				} else {
33					false
34				}
35			}
36			(Self::Object(a), Self::Object(b)) => {
37				if a.len() == b.len() {
38					for entry in a {
39						match b.get_unique(&*entry.key).expect("invalid JSON-LD") {
40							Some(value) => {
41								if !entry.value.compare(value) {
42									return false;
43								}
44							}
45							None => return false,
46						}
47					}
48
49					true
50				} else {
51					false
52				}
53			}
54			_ => false,
55		}
56	}
57}