use core::fmt;
pub struct Exclusive<T: ?Sized> {
inner: T,
}
unsafe impl<T: ?Sized> Sync for Exclusive<T> {}
impl<T> Exclusive<T> {
pub const fn new(inner: T) -> Self {
Self { inner }
}
pub fn into_inner(self) -> T {
self.inner
}
}
impl<T: ?Sized> Exclusive<T> {
pub const fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
}
impl<T: ?Sized> fmt::Debug for Exclusive<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Exclusive").finish_non_exhaustive()
}
}
#[cfg(test)]
#[commonware_macros::test_group("miri")]
mod tests {
use super::Exclusive;
use std::cell::Cell;
#[test]
fn test_exclusive_is_sync_and_grants_exclusive_access() {
fn assert_sync<T: Sync>(_: &T) {}
let mut exclusive = Exclusive::new(Cell::new(1u32));
assert_sync(&exclusive);
std::thread::scope(|scope| {
let shared = &exclusive;
scope.spawn(move || {
assert_eq!(format!("{shared:?}"), "Exclusive { .. }");
});
});
exclusive.get_mut().set(2);
assert_eq!(exclusive.into_inner().into_inner(), 2);
}
}