1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#[macro_export]
macro_rules! make_set_type {
	($name:ident ($internal:ident) / $type:ident + $max:ident) => {
		use std::ops::*;
		mod serde_compat {
			use super::$max;
			use serde::{de::{Visitor, SeqAccess}, Serializer, Deserializer};
			pub(crate) fn serialize<S>(t: &$internal, s: S) -> Result<S::Ok, S::Error>
			where
				S: Serializer,
			{
				let b: Vec<u8> = (0..$max).into_iter().filter(|x| (t >> x & 1) != 0).collect();
				s.serialize_bytes(&b)
			}
			pub(crate) fn deserialize<'de, D>(d: D) -> Result<$internal, D::Error>
			where
				D: Deserializer<'de>
			{
				struct SetVisitor;
				impl<'de> Visitor<'de> for SetVisitor {
					type Value = $internal;
					fn expecting(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
						fmt.write_str(concat!("a nonempty sequence of numbers where 1 << n is than ", stringify!($internal::max_value(n))))
					}
					fn visit_seq<S>(self, mut seq: S) -> Result<$internal, S::Error>
					where
						S: SeqAccess<'de>,
					{
						let mut num = 0;
						while let Some(value) = seq.next_element::<u8>()? {
							num |= 1 << value;
						}
						Ok(num)
					}
				}
				d.deserialize_seq(SetVisitor)
			}
		}
		#[doc = "A bit set of for filtering and/or smaller costs of storage."]
		#[derive(Clone, Copy, Default, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
		pub struct $name(#[serde(with = "serde_compat")] $internal);
		impl $name {
			pub fn new() -> Self {
				$name(0)
			}
			#[doc = "Self contains type"]
			pub fn has<T: Into<$type>>(self, other: T) -> bool {
				let amp = self.0 & (1 << other.into() as u8);
				amp != 0
			}
			#[doc = "Self is contained in part by other"]
			pub fn contains<T: Into<Self>>(self, other: T) -> bool {
				(self & other.into()).0 != 0
			}
			#[doc = "Self is contained in full by other"]
			pub fn contained<T: Into<Self>>(self, other: T) -> bool {
				(self & other.into()) == self
			}
		}
		#[doc = "Utility for converting a single type into a set of itself"]
		impl<T: Into<$type>> From<T> for $name {
			fn from(val: T) -> Self {
				$name(1 << val.into() as u8)
			}
		}
		#[doc = "Utility for converting an optional type into a set of itself (with full state if none)"]
		impl<T: Into<$name>> From<Option<T>> for $name {
			fn from(val: Option<T>) -> Self {
				if let Some(v) = val { v.into() }
				else { $name($internal::max_value()) }
			}
		}
		#[doc = "Utility for converting a list of type-alike into a set of type"]
		impl<T: Into<$type>> From<Vec<T>> for $name {
			fn from(list: Vec<T>) -> Self {
				::std::iter::FromIterator::from_iter(list)
			}
		}
		#[doc = "Utility for converting an iterable of type-alike into a set of type"]
		impl<T: Into<$type>> ::std::iter::FromIterator<T> for $name {
			fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
				let mut data = $name(0);
				for child in iter {
					data += child.into();
				}
				data
			}
		}
		#[doc = "Utility for the opposite of this set"]
		impl Not for $name {
			type Output = Self;
			fn not(self) -> Self {
				$name(!self.0)
			}
		}
		// Somehow clippy finds this suspicious but not the other ones.
		#[allow(clippy::suspicious_op_assign_impl)]
		#[doc = "Utility for adding type to this bit set"]
		impl AddAssign<$type> for $name {
			fn add_assign(&mut self, rhs: $type) {
				self.0 |= 1 << rhs as u8;
			}
		}
		#[doc = "Utility for removing type from this bit set"]
		impl SubAssign<$type> for $name {
			fn sub_assign(&mut self, rhs: $type) {
				self.0 &= !(1 << rhs as u8);
			}
		}
		#[doc = "Utility for combining two sets"]
		impl BitOrAssign for $name {
			fn bitor_assign(&mut self, rhs: Self) {
				self.0 |= rhs.0;
			}
		}
		#[doc = "Utility for the difference of two sets"]
		impl BitXor for $name {
			type Output = Self;
			fn bitxor(self, rhs: Self) -> Self {
				$name(self.0 ^ rhs.0)
			}
		}
		#[doc = "Utility for combining two sets"]
		impl BitOr for $name {
			type Output = Self;
			fn bitor(self, rhs: Self) -> Self {
				$name(self.0 | rhs.0)
			}
		}
		#[doc = "Utility for the intersection of two sets"]
		impl BitAnd for $name {
			type Output = Self;
			fn bitand(self, rhs: Self) -> Self {
				$name(self.0 & rhs.0)
			}
		}
	};
}