ringbuf/traits/
observer.rs

1use super::{utils::modulus, Based};
2use core::{mem::MaybeUninit, num::NonZeroUsize};
3
4/// Ring buffer observer.
5///
6/// Can observe ring buffer state but cannot safely access its data.
7pub trait Observer {
8    type Item: Sized;
9
10    /// Capacity of the ring buffer.
11    ///
12    /// It is constant during the whole ring buffer lifetime.
13    fn capacity(&self) -> NonZeroUsize;
14
15    /// Index of the last item in the ring buffer.
16    ///
17    /// Index value is in range `0..(2 * capacity)`.
18    fn read_index(&self) -> usize;
19    /// Index of the next empty slot in the ring buffer.
20    ///
21    /// Index value is in range `0..(2 * capacity)`.
22    fn write_index(&self) -> usize;
23
24    /// Get slice between `start` and `end` indices.
25    ///
26    /// # Safety
27    ///
28    /// Slice must not overlap with any mutable slice existing at the same time.
29    ///
30    /// Non-`Sync` items must not be accessed from multiple threads at the same time.
31    unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&[MaybeUninit<Self::Item>], &[MaybeUninit<Self::Item>]);
32
33    /// Get mutable slice between `start` and `end` indices.
34    ///
35    /// # Safety
36    ///
37    /// There must not exist overlapping slices at the same time.
38    unsafe fn unsafe_slices_mut(&self, start: usize, end: usize) -> (&mut [MaybeUninit<Self::Item>], &mut [MaybeUninit<Self::Item>]);
39
40    /// Whether read end is held by consumer.
41    fn read_is_held(&self) -> bool;
42    /// Whether write end is held by producer.
43    fn write_is_held(&self) -> bool;
44
45    /// The number of items stored in the buffer.
46    ///
47    /// *Actual number may be greater or less than returned value due to concurring activity of producer or consumer respectively.*
48    fn occupied_len(&self) -> usize {
49        let modulus = modulus(self);
50        (modulus.get() + self.write_index() - self.read_index()) % modulus
51    }
52
53    /// The number of remaining free places in the buffer.
54    ///
55    /// *Actual number may be greater or less than returned value due to concurring activity of consumer or producer respectively.*
56    fn vacant_len(&self) -> usize {
57        let modulus = modulus(self);
58        (self.capacity().get() + self.read_index() - self.write_index()) % modulus
59    }
60
61    /// Checks if the ring buffer is empty.
62    ///
63    /// *The result may become irrelevant at any time because of concurring producer activity.*
64    #[inline]
65    fn is_empty(&self) -> bool {
66        self.read_index() == self.write_index()
67    }
68
69    /// Checks if the ring buffer is full.
70    ///
71    /// *The result may become irrelevant at any time because of concurring consumer activity.*
72    #[inline]
73    fn is_full(&self) -> bool {
74        self.vacant_len() == 0
75    }
76}
77
78/// Trait used for delegating observer methods.
79pub trait DelegateObserver: Based
80where
81    Self::Base: Observer,
82{
83}
84
85impl<D: DelegateObserver> Observer for D
86where
87    D::Base: Observer,
88{
89    type Item = <D::Base as Observer>::Item;
90
91    #[inline]
92    fn capacity(&self) -> NonZeroUsize {
93        self.base().capacity()
94    }
95
96    #[inline]
97    fn read_index(&self) -> usize {
98        self.base().read_index()
99    }
100    #[inline]
101    fn write_index(&self) -> usize {
102        self.base().write_index()
103    }
104
105    #[inline]
106    unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&[MaybeUninit<Self::Item>], &[MaybeUninit<Self::Item>]) {
107        self.base().unsafe_slices(start, end)
108    }
109    #[inline]
110    unsafe fn unsafe_slices_mut(&self, start: usize, end: usize) -> (&mut [MaybeUninit<Self::Item>], &mut [MaybeUninit<Self::Item>]) {
111        self.base().unsafe_slices_mut(start, end)
112    }
113
114    #[inline]
115    fn read_is_held(&self) -> bool {
116        self.base().read_is_held()
117    }
118    #[inline]
119    fn write_is_held(&self) -> bool {
120        self.base().write_is_held()
121    }
122
123    #[inline]
124    fn occupied_len(&self) -> usize {
125        self.base().occupied_len()
126    }
127
128    #[inline]
129    fn vacant_len(&self) -> usize {
130        self.base().vacant_len()
131    }
132
133    #[inline]
134    fn is_empty(&self) -> bool {
135        self.base().is_empty()
136    }
137
138    #[inline]
139    fn is_full(&self) -> bool {
140        self.base().is_full()
141    }
142}