ringbuf/wrap/
direct.rs

1//! Direct implementation.
2//!
3//! All changes are synchronized with the ring buffer immediately.
4
5use super::{frozen::Frozen, traits::Wrap};
6use crate::{
7    rb::RbRef,
8    traits::{
9        consumer::{impl_consumer_traits, Consumer},
10        producer::{impl_producer_traits, Producer},
11        Observer, RingBuffer,
12    },
13};
14use core::{
15    mem::{ManuallyDrop, MaybeUninit},
16    num::NonZeroUsize,
17    ptr,
18};
19
20/// Direct wrapper of a ring buffer.
21pub struct Direct<R: RbRef, const P: bool, const C: bool> {
22    rb: R,
23}
24
25/// Observer of a ring buffer.
26pub type Obs<R> = Direct<R, false, false>;
27/// Producer of a ring buffer.
28pub type Prod<R> = Direct<R, true, false>;
29/// Consumer of a ring buffer.
30pub type Cons<R> = Direct<R, false, true>;
31
32impl<R: RbRef> Clone for Obs<R> {
33    fn clone(&self) -> Self {
34        Self { rb: self.rb.clone() }
35    }
36}
37
38impl<R: RbRef, const P: bool, const C: bool> Direct<R, P, C> {
39    /// Create a new ring buffer direct wrapper.
40    ///
41    /// Panics if wrapper with matching rights already exists.
42    pub fn new(rb: R) -> Self {
43        if P {
44            assert!(!unsafe { rb.rb().hold_write(true) });
45        }
46        if C {
47            assert!(!unsafe { rb.rb().hold_read(true) });
48        }
49        Self { rb }
50    }
51
52    /// Get ring buffer observer.
53    pub fn observe(&self) -> Obs<R> {
54        Obs { rb: self.rb.clone() }
55    }
56
57    /// Freeze current state.
58    pub fn freeze(self) -> Frozen<R, P, C> {
59        let this = ManuallyDrop::new(self);
60        unsafe { Frozen::new_unchecked(ptr::read(&this.rb)) }
61    }
62
63    /// # Safety
64    ///
65    /// Must not be used after this call.
66    unsafe fn close(&mut self) {
67        if P {
68            self.rb().hold_write(false);
69        }
70        if C {
71            self.rb().hold_read(false);
72        }
73    }
74}
75
76impl<R: RbRef, const P: bool, const C: bool> Wrap for Direct<R, P, C> {
77    type RbRef = R;
78    fn rb_ref(&self) -> &R {
79        &self.rb
80    }
81    fn into_rb_ref(mut self) -> R {
82        unsafe {
83            self.close();
84            let this = ManuallyDrop::new(self);
85            ptr::read(&this.rb)
86        }
87    }
88}
89
90impl<R: RbRef, const P: bool, const C: bool> AsRef<Self> for Direct<R, P, C> {
91    fn as_ref(&self) -> &Self {
92        self
93    }
94}
95impl<R: RbRef, const P: bool, const C: bool> AsMut<Self> for Direct<R, P, C> {
96    fn as_mut(&mut self) -> &mut Self {
97        self
98    }
99}
100
101impl<R: RbRef, const P: bool, const C: bool> Observer for Direct<R, P, C> {
102    type Item = <R::Rb as Observer>::Item;
103
104    #[inline]
105    fn capacity(&self) -> NonZeroUsize {
106        self.rb().capacity()
107    }
108    #[inline]
109    fn read_index(&self) -> usize {
110        self.rb().read_index()
111    }
112    #[inline]
113    fn write_index(&self) -> usize {
114        self.rb().write_index()
115    }
116    #[inline]
117    unsafe fn unsafe_slices(&self, start: usize, end: usize) -> (&[MaybeUninit<Self::Item>], &[MaybeUninit<Self::Item>]) {
118        self.rb().unsafe_slices(start, end)
119    }
120    #[inline]
121    unsafe fn unsafe_slices_mut(&self, start: usize, end: usize) -> (&mut [MaybeUninit<Self::Item>], &mut [MaybeUninit<Self::Item>]) {
122        self.rb().unsafe_slices_mut(start, end)
123    }
124    #[inline]
125    fn read_is_held(&self) -> bool {
126        self.rb().read_is_held()
127    }
128    #[inline]
129    fn write_is_held(&self) -> bool {
130        self.rb().write_is_held()
131    }
132}
133
134impl<R: RbRef> Producer for Prod<R> {
135    #[inline]
136    unsafe fn set_write_index(&self, value: usize) {
137        self.rb().set_write_index(value)
138    }
139}
140
141impl<R: RbRef> Consumer for Cons<R> {
142    #[inline]
143    unsafe fn set_read_index(&self, value: usize) {
144        self.rb().set_read_index(value)
145    }
146}
147
148impl<R: RbRef, const P: bool, const C: bool> Drop for Direct<R, P, C> {
149    fn drop(&mut self) {
150        unsafe { self.close() };
151    }
152}
153
154impl_producer_traits!(Prod<R: RbRef>);
155impl_consumer_traits!(Cons<R: RbRef>);