Skip to content

Commit 4ddf007

Browse files
sealed: add more functions
1 parent d052ea0 commit 4ddf007

File tree

5 files changed

+268
-204
lines changed

5 files changed

+268
-204
lines changed

src/sealed.rs

Lines changed: 0 additions & 204 deletions
This file was deleted.

src/sealed/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//! Collections that never leak references to their content, and therefore can be safely accessed via shared references.
2+
3+
mod queue;
4+
mod set;
5+
mod utils;
6+
7+
pub use queue::Queue;
8+
pub use set::Set;

src/sealed/queue.rs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
use super::utils::UnsafeWrapper;
2+
use std::collections::{VecDeque, vec_deque};
3+
use std::fmt;
4+
5+
/// FIFO queue that never leaks references to its content
6+
pub struct Queue<T>(UnsafeWrapper<VecDeque<T>>);
7+
8+
impl<T> Queue<T> {
9+
pub fn new() -> Self {
10+
Self(UnsafeWrapper::new(VecDeque::new()))
11+
}
12+
13+
pub fn with_capacity(capacity: usize) -> Self {
14+
Self(UnsafeWrapper::new(VecDeque::with_capacity(capacity)))
15+
}
16+
17+
pub fn push(&self, item: T) {
18+
// SAFETY: `with()` is never invoked recursively
19+
unsafe { self.0.with(|inner| inner.push_back(item)) }
20+
}
21+
22+
pub fn pop(&self) -> Option<T> {
23+
// SAFETY: `with()` is never invoked recursively
24+
unsafe { self.0.with(|inner| inner.pop_front()) }
25+
}
26+
27+
pub fn contains(&self, item: &T) -> bool
28+
where
29+
T: PartialEq<T>,
30+
{
31+
// SAFETY: `with()` is never invoked recursively
32+
unsafe { self.0.with(|inner| inner.contains(item)) }
33+
}
34+
35+
pub fn remove_all(&self, item: &T) -> bool
36+
where
37+
T: PartialEq<T>,
38+
{
39+
// SAFETY: `with()` is never invoked recursively
40+
unsafe {
41+
self.0.with(|inner| {
42+
let initial_len = inner.len();
43+
inner.retain(|e| e != item);
44+
inner.len() != initial_len
45+
})
46+
}
47+
}
48+
49+
pub fn clear(&self) {
50+
// SAFETY: `with()` is never invoked recursively
51+
unsafe { self.0.with(|inner| inner.clear()) }
52+
}
53+
54+
pub fn len(&self) -> usize {
55+
// SAFETY: `with()` is never invoked recursively
56+
unsafe { self.0.with(|inner| inner.len()) }
57+
}
58+
59+
pub fn capacity(&self) -> usize {
60+
// SAFETY: `with()` is never invoked recursively
61+
unsafe { self.0.with(|inner| inner.capacity()) }
62+
}
63+
64+
pub fn is_empty(&self) -> bool {
65+
self.len() == 0
66+
}
67+
68+
pub fn into_inner(self) -> VecDeque<T> {
69+
self.0.into_inner()
70+
}
71+
}
72+
73+
impl<T> From<VecDeque<T>> for Queue<T> {
74+
fn from(vec_deque: VecDeque<T>) -> Self {
75+
Self(UnsafeWrapper::new(vec_deque))
76+
}
77+
}
78+
79+
impl<T: fmt::Debug> fmt::Debug for Queue<T> {
80+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81+
// SAFETY: `with()` is never invoked recursively
82+
unsafe { self.0.with(|inner| inner.fmt(f)) }
83+
}
84+
}
85+
86+
impl<T> Default for Queue<T> {
87+
fn default() -> Self {
88+
Self::new()
89+
}
90+
}
91+
92+
impl<T: Clone> Clone for Queue<T> {
93+
fn clone(&self) -> Self {
94+
// SAFETY: `with()` is never invoked recursively
95+
unsafe { self.0.with(|inner| Self(UnsafeWrapper::new(inner.clone()))) }
96+
}
97+
}
98+
99+
impl<T> IntoIterator for Queue<T> {
100+
type Item = T;
101+
type IntoIter = vec_deque::IntoIter<T>;
102+
103+
fn into_iter(self) -> Self::IntoIter {
104+
self.0.into_inner().into_iter()
105+
}
106+
}
107+
108+
#[cfg(test)]
109+
mod tests {
110+
use super::*;
111+
use static_assertions::{assert_impl_all, assert_not_impl_any};
112+
use std::{rc::Rc, sync::Arc};
113+
114+
#[test]
115+
fn test_queue_is_send_but_not_sync() {
116+
assert_impl_all!(Queue<usize>: std::marker::Send);
117+
assert_not_impl_any!(Queue<Rc<usize>>: std::marker::Send);
118+
assert_not_impl_any!(Queue<Arc<usize>>: Sync);
119+
assert_not_impl_any!(Arc<Queue<usize>>: std::marker::Send, Sync);
120+
}
121+
}

0 commit comments

Comments
 (0)