1#[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
22pub struct Direct<R: RbRef, const P: bool, const C: bool> {
24 rb: R,
25}
26
27pub type Obs<R> = Direct<R, false, false>;
29pub type Prod<R> = Direct<R, true, false>;
31pub 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 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 pub fn observe(&self) -> Obs<R> {
56 Obs { rb: self.rb.clone() }
57 }
58
59 #[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 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>);