wsio_core/atomic/
status.rs

1use std::{
2    marker::PhantomData,
3    sync::atomic::{
4        AtomicU8,
5        Ordering,
6    },
7};
8
9use anyhow::{
10    Result,
11    anyhow,
12};
13
14pub struct AtomicStatus<T: Into<u8> + TryFrom<u8>> {
15    _marker: PhantomData<T>,
16    inner: AtomicU8,
17}
18
19impl<T: Into<u8> + TryFrom<u8>> AtomicStatus<T> {
20    #[inline]
21    pub fn new(status: T) -> Self {
22        Self {
23            _marker: PhantomData,
24            inner: AtomicU8::new(status.into()),
25        }
26    }
27
28    // Public methods
29
30    #[inline]
31    pub fn get(&self) -> T {
32        T::try_from(self.inner.load(Ordering::SeqCst)).ok().unwrap()
33    }
34
35    #[inline]
36    pub fn is(&self, status: T) -> bool {
37        self.inner.load(Ordering::SeqCst) == status.into()
38    }
39
40    #[inline]
41    pub fn store(&self, status: T) {
42        self.inner.store(status.into(), Ordering::SeqCst);
43    }
44
45    #[inline]
46    pub fn try_transition(&self, from: T, to: T) -> Result<()> {
47        self.inner
48            .compare_exchange(from.into(), to.into(), Ordering::SeqCst, Ordering::SeqCst)
49            .map(|_| ())
50            .map_err(|_| anyhow!("Failed to transition status"))
51    }
52}