Skip to main content

infinity_pool/builders/
pinned_raw_builder.rs

1use std::marker::PhantomData;
2
3use crate::{DropPolicy, RawPinnedPool};
4
5/// Creates an instance of [`RawPinnedPool`].
6#[derive(Debug)]
7#[must_use]
8pub struct RawPinnedPoolBuilder<T> {
9    drop_policy: DropPolicy,
10
11    _type: PhantomData<T>,
12
13    _not_send: PhantomData<*const ()>,
14}
15
16impl<T> RawPinnedPoolBuilder<T> {
17    /// Creates a new instance of the builder with the default options.
18    pub fn new() -> Self {
19        Self {
20            drop_policy: DropPolicy::default(),
21            _type: PhantomData,
22            _not_send: PhantomData,
23        }
24    }
25
26    /// Defines the drop policy for the pool. Optional.
27    pub fn drop_policy(mut self, drop_policy: DropPolicy) -> Self {
28        self.drop_policy = drop_policy;
29        self
30    }
31
32    /// Validates the options and creates the pool.
33    #[must_use]
34    pub fn build(self) -> RawPinnedPool<T> {
35        RawPinnedPool::new_inner(self.drop_policy)
36    }
37}
38
39impl<T> Default for RawPinnedPoolBuilder<T> {
40    fn default() -> Self {
41        Self::new()
42    }
43}
44
45#[cfg(test)]
46#[allow(
47    clippy::indexing_slicing,
48    clippy::multiple_unsafe_ops_per_block,
49    clippy::undocumented_unsafe_blocks,
50    reason = "tests focus on succinct code and do not need to tick all the boxes"
51)]
52#[cfg_attr(coverage_nightly, coverage(off))]
53mod tests {
54    use static_assertions::assert_not_impl_any;
55
56    use super::*;
57
58    assert_not_impl_any!(RawPinnedPoolBuilder<i32>: Send, Sync);
59
60    #[test]
61    fn builder_with_drop_policy() {
62        // Test that MayDropContents allows pool to be dropped with items still in it
63        let mut pool = RawPinnedPoolBuilder::<String>::new()
64            .drop_policy(DropPolicy::MayDropContents)
65            .build();
66
67        // Insert an item and deliberately DO NOT remove it
68        let _handle = pool.insert("test string".to_string());
69        assert_eq!(pool.len(), 1);
70
71        // Pool should be dropped successfully even with items still in it
72        // (This is the whole point of MayDropContents policy)
73        drop(pool);
74    }
75
76    #[test]
77    #[should_panic]
78    fn builder_with_must_not_drop_contents_policy() {
79        // Test that MustNotDropContents panics when pool is dropped with items
80        let mut pool = RawPinnedPoolBuilder::<i64>::new()
81            .drop_policy(DropPolicy::MustNotDropContents)
82            .build();
83
84        // Insert an item and deliberately DO NOT remove it
85        let _handle = pool.insert(9999_i64);
86        assert_eq!(pool.len(), 1);
87
88        // Pool should panic when dropped with items still in it
89        // (This is the whole point of MustNotDropContents policy)
90        drop(pool);
91    }
92
93    #[test]
94    fn builder_default_works() {
95        let mut pool = RawPinnedPoolBuilder::<u32>::default().build();
96
97        assert_eq!(pool.len(), 0);
98        assert!(pool.is_empty());
99        assert_eq!(pool.capacity(), 0);
100
101        // Verify it is functional
102        let handle = pool.insert(123_u32);
103        assert_eq!(unsafe { *handle.as_ref() }, 123);
104        // SAFETY: Handle is valid and from this pool
105        unsafe {
106            pool.remove(handle.into_shared());
107        }
108    }
109
110    #[test]
111    fn builder_via_pool_static_method() {
112        let mut pool = RawPinnedPool::<u64>::builder().build();
113
114        assert_eq!(pool.len(), 0);
115        assert!(pool.is_empty());
116        assert_eq!(pool.capacity(), 0);
117
118        // Test functionality
119        let handle = pool.insert(64);
120        assert_eq!(unsafe { *handle.as_ref() }, 64);
121
122        unsafe {
123            pool.remove(handle.into_shared());
124        }
125    }
126}