anchored_pool/
other_utils.rs

1use std::mem;
2use std::error::Error;
3use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
4
5#[cfg(feature = "clone-behavior")]
6use clone_behavior::{DeepClone, MirroredClone, Speed};
7
8
9/// An error that may, instead of waiting for a `Resource` to become available, be returned if no
10/// `Resource`s were available in a bounded pool.
11#[derive(Debug, Clone, Copy)]
12pub struct ResourcePoolEmpty;
13
14impl Display for ResourcePoolEmpty {
15    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
16        write!(
17            f,
18            "a bounded resource pool operation was not performed \
19             because there were no `Resource`s available",
20        )
21    }
22}
23
24impl Error for ResourcePoolEmpty {}
25
26/// An error that may, instead of waiting for a buffer to become available, be returned if no
27/// buffers were available in a bounded pool.
28#[derive(Debug, Clone, Copy)]
29pub struct OutOfBuffers;
30
31impl Display for OutOfBuffers {
32    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
33         write!(
34            f,
35            "a bounded buffer pool operation was not performed \
36             because there were no available buffers",
37        )
38    }
39}
40
41impl Error for OutOfBuffers {}
42
43/// Trait for the operation performed when a `Resource` is returned to a pool.
44pub trait ResetResource<Resource> {
45    /// Operation performed when a `Resource` is returned to a pool.
46    ///
47    /// Intended for resetting the `Resource` to some blank state for future use.
48    fn reset(&self, resource: &mut Resource);
49}
50
51impl<Resource, F: Fn(&mut Resource)> ResetResource<Resource> for F {
52    #[inline]
53    fn reset(&self, resource: &mut Resource) {
54        self(resource);
55    }
56}
57
58/// Implements [`ResetResource`] with a no-op. Can be used when a `Resource` does not need to be
59/// reset when it is returned to a pool.
60#[derive(Default, Debug, Clone, Copy)]
61pub struct ResetNothing;
62
63impl<Resource> ResetResource<Resource> for ResetNothing {
64    /// Do nothing to reset the resource.
65    fn reset(&self, _resource: &mut Resource) {}
66}
67
68#[cfg(feature = "clone-behavior")]
69impl<S: Speed> DeepClone<S> for ResetNothing {
70    #[inline]
71    fn deep_clone(&self) -> Self {
72        *self
73    }
74}
75
76#[cfg(feature = "clone-behavior")]
77impl<S: Speed> MirroredClone<S> for ResetNothing {
78    #[inline]
79    fn mirrored_clone(&self) -> Self {
80        *self
81    }
82}
83
84/// An implementation of <code>[ResetResource]<Vec\<u8\>></code>.
85///
86/// `ResetBuffer` resets a `Vec<u8>` by either clearing it without reducing its capacity, or by
87/// resetting it to a new zero-capacity `Vec<u8>` if its capacity exceeds a chosen maximum
88/// capacity.
89#[derive(Debug, Clone, Copy)]
90pub struct ResetBuffer {
91    /// Must not be mutated after construction, in order to satisfy the semantics
92    /// of our implementation of `MirroredClone`.
93    max_buffer_capacity: usize,
94}
95
96impl ResetBuffer {
97    /// Get an implementation of <code>[ResetResource]<Vec\<u8\>></code>.
98    ///
99    /// The created `ResetBuffer` resets a `Vec<u8>` by either clearing it without reducing its
100    /// capacity, or by resetting it to a new zero-capacity `Vec<u8>` if its capacity exceeds
101    /// `max_buffer_capacity`.
102    #[inline]
103    #[must_use]
104    pub const fn new(max_buffer_capacity: usize) -> Self {
105        Self {
106            max_buffer_capacity,
107        }
108    }
109}
110
111impl ResetResource<Vec<u8>> for ResetBuffer {
112    #[inline]
113    fn reset(&self, resource: &mut Vec<u8>) {
114        if resource.capacity() > self.max_buffer_capacity {
115            // Take and drop the large buffer
116            let _large_buf = mem::take(resource);
117        } else {
118            resource.clear();
119        }
120    }
121}
122
123#[cfg(feature = "clone-behavior")]
124impl<S: Speed> DeepClone<S> for ResetBuffer {
125    #[inline]
126    fn deep_clone(&self) -> Self {
127        *self
128    }
129}
130
131#[cfg(feature = "clone-behavior")]
132impl<S: Speed> MirroredClone<S> for ResetBuffer {
133    #[inline]
134    fn mirrored_clone(&self) -> Self {
135        *self
136    }
137}