ringbuf/wrap/
direct.rs
1use 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
20pub struct Direct<R: RbRef, const P: bool, const C: bool> {
22 rb: R,
23}
24
25pub type Obs<R> = Direct<R, false, false>;
27pub type Prod<R> = Direct<R, true, false>;
29pub 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 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 pub fn observe(&self) -> Obs<R> {
54 Obs { rb: self.rb.clone() }
55 }
56
57 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 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>);