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
use bit_set::BitSet;
use std::ops::{BitAnd, BitOr, BitOrAssign};
/// A set of field indices, backed by a bit set.
///
/// Used to track which fields are present in a [`SparseRecord`](super::SparseRecord)
/// or which fields are part of a type description. Supports set operations
/// like union (`|`), intersection (`&`), and membership tests.
///
/// # Examples
///
/// ```
/// use toasty_core::stmt::PathFieldSet;
///
/// let mut set = PathFieldSet::new();
/// set.insert(0);
/// set.insert(2);
/// assert!(set.contains(0_usize));
/// assert!(!set.contains(1_usize));
/// assert_eq!(set.len(), 2);
/// ```
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PathFieldSet {
container: BitSet<u32>,
}
/// An iterator over the field indices in a [`PathFieldSet`].
///
/// Generic over the underlying `bit-set` iterator rather than naming it: as of
/// `bit-set` 0.10.1 the concrete `Iter` type lives in a private module and can
/// no longer be referred to directly.
pub struct PathFieldSetIter<I> {
inner: I,
len: usize,
}
impl<I: Iterator<Item = usize>> Iterator for PathFieldSetIter<I> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
let result = self.inner.next();
if result.is_some() {
self.len -= 1;
}
result
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
impl<I: Iterator<Item = usize>> ExactSizeIterator for PathFieldSetIter<I> {}
impl PathFieldSet {
/// Creates an empty field set.
pub fn new() -> Self {
Self::default()
}
/// Creates a field set from a slice of values convertible to `usize`.
pub fn from_slice<T>(fields: &[T]) -> Self
where
for<'a> &'a T: Into<usize>,
{
Self {
container: fields.iter().map(Into::into).collect(),
}
}
/// Returns `true` if the set contains the given field index.
pub fn contains(&self, val: impl Into<usize>) -> bool {
self.container.contains(val.into())
}
/// Returns an iterator over the field indices in ascending order.
pub fn iter(&self) -> PathFieldSetIter<impl Iterator<Item = usize> + '_> {
PathFieldSetIter {
inner: self.container.iter(),
len: self.container.count(),
}
}
/// Returns `true` if the set contains no field indices.
pub fn is_empty(&self) -> bool {
self.container.is_empty()
}
/// Returns the number of field indices in the set.
pub fn len(&self) -> usize {
self.container.count()
}
/// Inserts a field index into the set.
pub fn insert(&mut self, val: usize) {
self.container.insert(val);
}
}
impl BitOr for PathFieldSet {
type Output = Self;
fn bitor(mut self, rhs: Self) -> Self {
self.container.union_with(&rhs.container);
self
}
}
impl BitOrAssign for PathFieldSet {
fn bitor_assign(&mut self, rhs: Self) {
self.container.union_with(&rhs.container);
}
}
impl BitAnd for PathFieldSet {
type Output = Self;
fn bitand(mut self, rhs: Self) -> Self {
self.container.intersect_with(&rhs.container);
self
}
}
impl FromIterator<usize> for PathFieldSet {
fn from_iter<T: IntoIterator<Item = usize>>(iter: T) -> Self {
Self {
container: BitSet::from_iter(iter),
}
}
}