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
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.iter().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()
}
/// 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()
}
/// 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),
}
}
}