1use atomic_polyfill::{AtomicBool, Ordering};
2
3pub trait SplitState: Clone {
4 fn same(&self, other: &Self) -> bool;
5 fn is_open(&self) -> bool;
6 fn set_open(&self, open: bool);
7}
8
9pub trait SplitStateContainer {
10 type State: SplitState;
11
12 fn state(self) -> Self::State;
13}
14
15pub struct SplitConnectionState {
16 is_open: AtomicBool,
17}
18
19impl Default for SplitConnectionState {
20 #[inline]
21 fn default() -> Self {
22 Self {
23 is_open: AtomicBool::new(true),
24 }
25 }
26}
27
28impl<'a> SplitStateContainer for &'a mut SplitConnectionState {
29 type State = &'a SplitConnectionState;
30
31 fn state(self) -> Self::State {
32 &*self
33 }
34}
35
36impl SplitState for &SplitConnectionState {
37 fn is_open(&self) -> bool {
38 self.is_open.load(Ordering::Acquire)
39 }
40
41 fn set_open(&self, open: bool) {
42 self.is_open.store(open, Ordering::Release);
43 }
44
45 fn same(&self, other: &Self) -> bool {
46 core::ptr::eq(*self, *other)
47 }
48}
49
50#[cfg(feature = "std")]
51pub use stdlib::ManagedSplitState;
52
53#[cfg(feature = "std")]
54mod stdlib {
55 use super::*;
56 use std::sync::Arc;
57
58 #[derive(Clone)]
59 pub struct ManagedSplitState(Arc<SplitConnectionState>);
60 impl ManagedSplitState {
61 pub(crate) fn new() -> Self {
62 Self(Arc::new(SplitConnectionState::default()))
63 }
64 }
65
66 impl SplitStateContainer for ManagedSplitState {
67 type State = ManagedSplitState;
68
69 fn state(self) -> Self::State {
70 self
71 }
72 }
73
74 impl SplitState for ManagedSplitState {
75 fn is_open(&self) -> bool {
76 self.0.as_ref().is_open()
77 }
78
79 fn set_open(&self, open: bool) {
80 self.0.as_ref().set_open(open)
81 }
82
83 fn same(&self, other: &Self) -> bool {
84 Arc::ptr_eq(&self.0, &other.0)
85 }
86 }
87}