ringbuf/traits/
producer.rs1use super::{
2 observer::{DelegateObserver, Observer},
3 utils::modulus,
4};
5#[cfg(feature = "std")]
6use crate::utils::slice_assume_init_mut;
7use crate::utils::write_slice;
8use core::mem::MaybeUninit;
9#[cfg(feature = "std")]
10use std::{
11 cmp,
12 io::{self, Read},
13};
14
15pub trait Producer: Observer {
17 unsafe fn set_write_index(&self, value: usize);
25
26 unsafe fn advance_write_index(&self, count: usize) {
34 self.set_write_index((self.write_index() + count) % modulus(self));
35 }
36
37 fn vacant_slices(&self) -> (&[MaybeUninit<Self::Item>], &[MaybeUninit<Self::Item>]) {
41 unsafe { self.unsafe_slices(self.write_index(), self.read_index() + self.capacity().get()) }
42 }
43
44 fn vacant_slices_mut(&mut self) -> (&mut [MaybeUninit<Self::Item>], &mut [MaybeUninit<Self::Item>]) {
54 unsafe { self.unsafe_slices_mut(self.write_index(), self.read_index() + self.capacity().get()) }
55 }
56
57 fn try_push(&mut self, elem: Self::Item) -> Result<(), Self::Item> {
61 if !self.is_full() {
62 unsafe {
63 self.vacant_slices_mut().0.get_unchecked_mut(0).write(elem);
64 self.advance_write_index(1)
65 };
66 Ok(())
67 } else {
68 Err(elem)
69 }
70 }
71
72 fn push_iter<I: Iterator<Item = Self::Item>>(&mut self, mut iter: I) -> usize {
80 let (left, right) = self.vacant_slices_mut();
81 let mut count = 0;
82 for place in left.iter_mut().chain(right.iter_mut()) {
83 match iter.next() {
84 Some(elem) => unsafe { place.as_mut_ptr().write(elem) },
85 None => break,
86 }
87 count += 1;
88 }
89 unsafe { self.advance_write_index(count) };
90 count
91 }
92
93 fn push_slice(&mut self, elems: &[Self::Item]) -> usize
97 where
98 Self::Item: Copy,
99 {
100 let (left, right) = self.vacant_slices_mut();
101 let count = if elems.len() < left.len() {
102 write_slice(&mut left[..elems.len()], elems);
103 elems.len()
104 } else {
105 let (left_elems, elems) = elems.split_at(left.len());
106 write_slice(left, left_elems);
107 left.len()
108 + if elems.len() < right.len() {
109 write_slice(&mut right[..elems.len()], elems);
110 elems.len()
111 } else {
112 write_slice(right, &elems[..right.len()]);
113 right.len()
114 }
115 };
116 unsafe { self.advance_write_index(count) };
117 count
118 }
119
120 #[cfg(feature = "std")]
121 fn read_from<S: Read>(&mut self, reader: &mut S, count: Option<usize>) -> Option<io::Result<usize>>
130 where
131 Self: Producer<Item = u8>,
132 {
133 let (left, _) = self.vacant_slices_mut();
134 let count = cmp::min(count.unwrap_or(left.len()), left.len());
135 if count == 0 {
136 return None;
137 }
138
139 let buf = &mut left[..count];
140 buf.fill(MaybeUninit::new(0));
143 let left_init = unsafe { slice_assume_init_mut(buf) };
144
145 let read_count = match reader.read(left_init) {
146 Ok(n) => n,
147 Err(e) => return Some(Err(e)),
148 };
149 assert!(read_count <= count);
150 unsafe { self.advance_write_index(read_count) };
151 Some(Ok(read_count))
152 }
153}
154
155pub trait DelegateProducer: DelegateObserver
157where
158 Self::Base: Producer,
159{
160}
161
162impl<D: DelegateProducer> Producer for D
163where
164 D::Base: Producer,
165{
166 #[inline]
167 unsafe fn set_write_index(&self, value: usize) {
168 self.base().set_write_index(value)
169 }
170 #[inline]
171 unsafe fn advance_write_index(&self, count: usize) {
172 self.base().advance_write_index(count)
173 }
174
175 #[inline]
176 fn vacant_slices(&self) -> (&[core::mem::MaybeUninit<Self::Item>], &[core::mem::MaybeUninit<Self::Item>]) {
177 self.base().vacant_slices()
178 }
179
180 #[inline]
181 fn vacant_slices_mut(&mut self) -> (&mut [core::mem::MaybeUninit<Self::Item>], &mut [core::mem::MaybeUninit<Self::Item>]) {
182 self.base_mut().vacant_slices_mut()
183 }
184
185 #[inline]
186 fn try_push(&mut self, elem: Self::Item) -> Result<(), Self::Item> {
187 self.base_mut().try_push(elem)
188 }
189
190 #[inline]
191 fn push_iter<I: Iterator<Item = Self::Item>>(&mut self, iter: I) -> usize {
192 self.base_mut().push_iter(iter)
193 }
194
195 #[inline]
196 fn push_slice(&mut self, elems: &[Self::Item]) -> usize
197 where
198 Self::Item: Copy,
199 {
200 self.base_mut().push_slice(elems)
201 }
202}
203
204macro_rules! impl_producer_traits {
205 ($type:ident $(< $( $param:tt $( : $first_bound:tt $(+ $next_bound:tt )* )? ),+ >)?) => {
206
207 #[cfg(feature = "std")]
208 impl $(< $( $param $( : $first_bound $(+ $next_bound )* )? ),+ >)? std::io::Write for $type $(< $( $param ),+ >)?
209 where
210 Self: $crate::traits::Producer<Item = u8>,
211 {
212 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
213 let n = self.push_slice(buf);
214 if n == 0 {
215 Err(std::io::ErrorKind::WouldBlock.into())
216 } else {
217 Ok(n)
218 }
219 }
220 fn flush(&mut self) -> std::io::Result<()> {
221 Ok(())
222 }
223 }
224
225 impl $(< $( $param $( : $first_bound $(+ $next_bound )* )? ),+ >)? core::fmt::Write for $type $(< $( $param ),+ >)?
226 where
227 Self: $crate::traits::Producer<Item = u8>,
228 {
229 fn write_str(&mut self, s: &str) -> core::fmt::Result {
230 let n = self.push_slice(s.as_bytes());
231 if n != s.len() {
232 Err(core::fmt::Error::default())
233 } else {
234 Ok(())
235 }
236 }
237 }
238 };
239 }
240pub(crate) use impl_producer_traits;