extern crate alloc;
use alloc::sync::Arc;
use core::fmt::{Debug, Formatter};
use core::ops::Deref;
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
pub struct SynchronizedOptional<T> {
inner: RwLock<Option<Arc<T>>>,
}
impl<T> Default for SynchronizedOptional<T> {
fn default() -> Self {
SynchronizedOptional::empty()
}
}
impl<T> SynchronizedOptional<T> {
#[must_use]
pub fn empty() -> Self {
Self {
inner: RwLock::new(None),
}
}
#[must_use]
pub fn new(value: T) -> Self {
Self {
inner: RwLock::new(Some(Arc::new(value))),
}
}
#[must_use]
pub fn new_shared(value: Arc<T>) -> Self {
Self {
inner: RwLock::new(Some(value)),
}
}
#[must_use]
pub fn get(&self) -> Option<Arc<T>> {
if let Ok(read) = self.inner.read() {
return read.clone();
}
None
}
pub fn set(&self, value: Option<T>) -> Result<(), Option<T>> {
if let Ok(mut write) = self.inner.write() {
*write = value.map(Arc::new);
return Ok(());
}
Err(value)
}
pub fn set_shared(&self, value: Arc<T>) -> Result<(), Arc<T>> {
if let Ok(mut write) = self.inner.write() {
*write = Some(value);
return Ok(());
}
Err(value)
}
pub fn take(&self) -> Option<Arc<T>> {
if let Ok(mut write) = self.inner.write() {
let out = write.clone();
*write = None;
return out;
}
None
}
pub fn swap(&self, value: T) -> Result<Option<Arc<T>>, T> {
if let Ok(mut write) = self.inner.write() {
let inner = write.clone();
*write = Some(Arc::new(value));
return Ok(inner);
}
Err(value)
}
pub fn swap_shared(&self, value: Arc<T>) -> Result<Option<Arc<T>>, Arc<T>> {
if let Ok(mut write) = self.inner.write() {
let inner = write.clone();
*write = Some(value);
return Ok(inner);
}
Err(value)
}
}
impl<T> Debug for SynchronizedOptional<T>
where
T: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}", self.get())
}
}
#[derive(Debug)]
pub struct SharedCell<T> {
inner: Arc<RwLock<Option<T>>>,
}
impl<T> Clone for SharedCell<T> {
fn clone(&self) -> Self {
SharedCell {
inner: self.inner.clone(),
}
}
}
impl<T> Default for SharedCell<T> {
fn default() -> Self {
SharedCell {
inner: Arc::new(RwLock::new(None)),
}
}
}
impl<T> From<Option<T>> for SharedCell<T> {
fn from(value: Option<T>) -> Self {
SharedCell {
inner: Arc::new(RwLock::new(value)),
}
}
}
impl<T> SharedCell<T> {
pub fn empty() -> Self {
None.into()
}
pub fn new(val: T) -> Self {
Some(val).into()
}
pub fn set(&self, val: T) {
if let Ok(mut lock) = self.inner.write() {
*lock = Some(val)
}
}
pub fn take(&self) -> Option<T> {
if let Ok(mut lock) = self.inner.write() {
return lock.take();
}
None
}
pub fn peek<V: Fn(Option<&T>)>(&self, func: V) {
if let Ok(lock) = self.inner.read() {
func(lock.as_ref())
}
}
pub fn as_ref(&self) -> ReadGuard<'_, T> {
if let Ok(lock) = self.inner.read() {
return Some(lock).into();
}
None.into()
}
pub fn peek_mut<V: FnMut(Option<&mut T>)>(&self, mut func: V) {
if let Ok(mut lock) = self.inner.write() {
func(lock.as_mut())
}
}
pub fn as_mut(&self) -> WriteGuard<'_,T> {
if let Ok(lock) = self.inner.write() {
return Some(lock).into();
}
None.into()
}
}
#[derive(Default)]
pub struct ReadGuard<'a, T> {
lock: Option<RwLockReadGuard<'a, Option<T>>>,
}
impl<'a, T> From<Option<RwLockReadGuard<'a, Option<T>>>> for ReadGuard<'a, T> {
fn from(value: Option<RwLockReadGuard<'a, Option<T>>>) -> Self {
ReadGuard { lock: value }
}
}
impl<T> Deref for ReadGuard<'_, T> {
type Target = Option<T>;
fn deref(&self) -> &Self::Target {
if let Some(lock) = &self.lock {
return lock.deref();
}
&None
}
}
#[derive(Default)]
pub struct WriteGuard<'a, T> {
lock: Option<RwLockWriteGuard<'a, Option<T>>>,
}
impl<T> Deref for WriteGuard<'_, T> {
type Target = Option<T>;
fn deref(&self) -> &Self::Target {
if let Some(lock) = &self.lock {
return lock.deref();
}
&None
}
}
impl<'a, T> From<Option<RwLockWriteGuard<'a, Option<T>>>> for WriteGuard<'a, T> {
fn from(value: Option<RwLockWriteGuard<'a, Option<T>>>) -> Self {
WriteGuard { lock: value }
}
}