owl_structural_model/
operand_set.rs1use crate::{OperandList, StructuralModelError};
4use serde::{Deserialize, Serialize};
5use std::collections::hash_map::DefaultHasher;
6use std::hash::{Hash, Hasher};
7use std::ops::Deref;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
14#[serde(transparent)]
15pub struct OperandSet<T, const MIN: usize = 0>(OperandList<T, MIN>);
16impl<T, const MIN: usize> OperandSet<T, MIN> {
17 pub fn try_new(items: Vec<T>) -> Result<Self, StructuralModelError> {
21 Ok(Self(OperandList::try_new(items)?))
22 }
23 #[must_use]
25 pub fn as_slice(&self) -> &[T] {
26 self.0.as_slice()
27 }
28}
29impl<T> OperandSet<T, 0> {
30 #[must_use]
32 pub fn new(items: Vec<T>) -> Self {
33 Self(OperandList::new(items))
34 }
35}
36impl<T, const MIN: usize> Deref for OperandSet<T, MIN> {
37 type Target = [T];
38 fn deref(&self) -> &Self::Target {
39 self.as_slice()
40 }
41}
42impl<'a, T, const MIN: usize> IntoIterator for &'a OperandSet<T, MIN> {
43 type Item = &'a T;
44 type IntoIter = std::slice::Iter<'a, T>;
45 fn into_iter(self) -> Self::IntoIter {
46 self.as_slice().iter()
47 }
48}
49impl<T: PartialEq, const MIN: usize> PartialEq for OperandSet<T, MIN> {
50 fn eq(&self, other: &Self) -> bool {
51 self.iter().all(|member| other.contains(member))
52 && other.iter().all(|member| self.contains(member))
53 }
54}
55impl<T: Eq, const MIN: usize> Eq for OperandSet<T, MIN> {}
56impl<T: Hash, const MIN: usize> Hash for OperandSet<T, MIN> {
57 fn hash<H: Hasher>(&self, state: &mut H) {
58 hash_unordered(self.as_slice(), state);
59 }
60}
61#[derive(Debug, Clone, Serialize, Deserialize)]
63#[serde(transparent)]
64pub struct UnorderedPair<T>([T; 2]);
65impl<T> UnorderedPair<T> {
66 #[must_use]
68 pub fn new(first: T, second: T) -> Self {
69 Self([first, second])
70 }
71 #[must_use]
73 pub fn as_slice(&self) -> &[T] {
74 &self.0
75 }
76}
77impl<T: PartialEq> PartialEq for UnorderedPair<T> {
78 fn eq(&self, other: &Self) -> bool {
79 (self.0[0] == other.0[0] && self.0[1] == other.0[1])
80 || (self.0[0] == other.0[1] && self.0[1] == other.0[0])
81 }
82}
83impl<T: Eq> Eq for UnorderedPair<T> {}
84impl<T: Hash> Hash for UnorderedPair<T> {
85 fn hash<H: Hasher>(&self, state: &mut H) {
86 hash_unordered(&self.0, state);
87 }
88}
89fn hash_unordered<T: Hash, H: Hasher>(members: &[T], state: &mut H) {
90 let mut hashes: Vec<u64> = members
92 .iter()
93 .map(|member| {
94 let mut digest = DefaultHasher::new();
95 member.hash(&mut digest);
96 digest.finish()
97 })
98 .collect();
99 hashes.sort_unstable();
100 hashes.dedup();
101 hashes.hash(state);
102}