SingletonToken

Struct SingletonToken 

Source
pub struct SingletonToken<Tag: ?Sized, Variant = SyncVariant>(/* private fields */);
Expand description

A singleton unforgeable token used to access the contents of a TokenLock.

It’s a singleton object, meaning there can be only one instance of SingletonToken<Tag> for each specific Tag. The instances of SingletonToken are solely distinguished by its type parameter Tag, making this type zero-sized.

This type lacks a Clone implementation to ensure exclusive access to TokenLock.

This type is invariant over Tag.

The second type parameter (Variant) is internal use only and exempt from the API stability guarantee.

§Sync-ness Conversion

SingletonToken can be converted back and forth to its non-Sync variation, UnsyncSingletonToken, by the following methods:

borrow_unsync doesn’t exist because &SingletonToken (the Sync variation) might already be owned by multiple threads, so converting them to the !Sync variation would violate the !Sync requirement.

The non-Sync variation can be used to access the contents of UnsyncTokenLock.

Implementations§

Source§

impl<Tag: ?Sized + SingletonTokenFactory, Variant: SingletonTokenVariant> SingletonToken<Tag, Variant>

Source

pub fn new() -> Result<SingletonTokenGuard<Tag, Variant>, SingletonTokenExhaustedError>

Construct Self, using Tag’s SingletonTokenFactory implementation to ensure only one token is present at once.

Returns an RAII guard that derefs to SingletonToken and returns the token when dropped.

§Examples
struct MyTag;
impl_singleton_token_factory!(MyTag);

type MyTokenLock<T> = TokenLock<T, SingletonTokenId<MyTag>>;
type MyToken = SingletonToken<MyTag>;
type MyTokenId = SingletonTokenId<MyTag>;

static LOCK1: MyTokenLock<u32> = MyTokenLock::new(MyTokenId::new(), 1);
static LOCK2: MyTokenLock<u32> = MyTokenLock::new(MyTokenId::new(), 1);

// Create a singleton token with a runtime uniqueness check
let mut token = MyToken::new().unwrap();

LOCK1.read(&*token);
LOCK2.write(&mut *token);

The SingletonTokenFactory implementation remembers that a token has been issued, so attempts to issue two tokens of the same tag will fail:

let token = SingletonToken::<MyTag>::new().unwrap();
assert!(SingletonToken::<MyTag>::new().is_err());
Source§

impl<Tag: ?Sized, Variant> SingletonToken<Tag, Variant>

Source

pub const unsafe fn new_unchecked() -> Self

Construct Self without checking the singleton invariant.

§Safety

Having more than one instance of SingletonToken<Tag> for a particular Tag violates Token’s requirements and allows a TokenLock to be mutably borrowed simultaneously, violating the pointer aliasing rules.

Source

pub fn id(&self) -> SingletonTokenId<Tag>

Construct an SingletonTokenId that equates to self.

Source

pub fn borrow(&self) -> SingletonTokenRef<'_, Tag, Variant>

Borrow self as SingletonTokenRef or UnsyncSingletonTokenRef of the same Sync-ness as Self.

SingletonTokenRef is truly zero-sized, so it’s more efficient to store and pass than &SingletonToken.

Source

pub fn borrow_mut(&mut self) -> SingletonTokenRefMut<'_, Tag, Variant>

Borrow self mutably as SingletonTokenRefMut or UnsyncSingletonTokenRefMut of the same Sync-ness as Self.

SingletonTokenRefMut is truly zero-sized, so it’s more efficient to store and pass than &mut SingletonToken.

Source§

impl<Tag: ?Sized> SingletonToken<Tag, UnsyncVariant>

Source

pub fn borrow_sync(&self) -> SingletonTokenRef<'_, Tag>

Borrow self: UnsyncSingletonToken as SingletonTokenRef.

Source

pub fn borrow_sync_mut(&mut self) -> SingletonTokenRefMut<'_, Tag>

Borrow self: UnsyncSingletonToken mutably as SingletonTokenRefMut.

Source§

impl<Tag: ?Sized> SingletonToken<Tag>

Source

pub fn borrow_unsync_mut(&mut self) -> UnsyncSingletonTokenRefMut<'_, Tag>

Borrow self: SingletonToken mutably as UnsyncSingletonTokenRefMut.

There is no borrow_unsync because that would allow UnsyncSingletonToken to be logically borrowed by multiple threads.

Source§

impl<Tag: ?Sized> SingletonToken<Tag>

Source

pub const fn into_unsync(self) -> UnsyncSingletonToken<Tag>

Convert SingletonToken to the !Sync variant.

Source§

impl<Tag: ?Sized> SingletonToken<Tag, UnsyncVariant>

Source

pub const fn into_sync(self) -> SingletonToken<Tag>

Convert UnsyncSingletonToken to the Sync variant.

Trait Implementations§

Source§

impl<Tag: ?Sized, Variant: SingletonTokenVariant> Debug for SingletonToken<Tag, Variant>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<Tag: ?Sized, Variant: SingletonTokenVariant> Hash for SingletonToken<Tag, Variant>

Source§

fn hash<H: Hasher>(&self, _: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<Tag: ?Sized, Variant: SingletonTokenVariant> PartialEq for SingletonToken<Tag, Variant>

Source§

fn eq(&self, _: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<Tag: ?Sized, Variant: SingletonTokenVariant> Token<SingletonTokenId<Tag>> for SingletonToken<Tag, Variant>

Source§

fn eq_id(&self, _: &SingletonTokenId<Tag>) -> bool

Source§

impl<Tag: ?Sized, Variant: SingletonTokenVariant> Eq for SingletonToken<Tag, Variant>

Auto Trait Implementations§

§

impl<Tag, Variant> Freeze for SingletonToken<Tag, Variant>
where Tag: ?Sized,

§

impl<Tag, Variant> RefUnwindSafe for SingletonToken<Tag, Variant>
where Variant: RefUnwindSafe, Tag: ?Sized,

§

impl<Tag, Variant> Send for SingletonToken<Tag, Variant>
where Variant: Send, Tag: ?Sized,

§

impl<Tag, Variant> Sync for SingletonToken<Tag, Variant>
where Variant: Sync, Tag: ?Sized,

§

impl<Tag, Variant> Unpin for SingletonToken<Tag, Variant>
where Variant: Unpin, Tag: ?Sized,

§

impl<Tag, Variant> UnwindSafe for SingletonToken<Tag, Variant>
where Variant: UnwindSafe, Tag: ?Sized,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.