Skip to main content

ringbuf/wrap/
direct.rs

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