Pass

Struct Pass 

Source
pub struct Pass(/* private fields */);
Expand description

A key for reading/writing to RwData

This key is necessary in order to prevent breakage of the number one rule of Rust: any number of shared references, or one exclusive reference.

When you call RwData::read, any call to RwData::write may end up breaking this rule, and vice-versa, which is why this struct is necessary.

One downside of this approach is that it is even more restrictive than Rust’s rule of thumb, since that one is enforced on individual instances, while this one is enforced on all RwDatas. This (as far as i know) cannot be circumvented, as a more advanced compile time checker (that distinguishes RwData<T>s of different Ts, for example) does not seem feasible without the use of unfinished features, which I am not willing to use.

Implementations§

Source§

impl Pass

Source

pub fn write_two<'a, L: 'static, R: 'static>( &'a mut self, lhs: &'a RwData<L>, rhs: &'a RwData<R>, ) -> (&'a mut L, &'a mut R)

Writes to two RwData at the same time

This can only be done when the RwDatas are of different types since, if they were of the same type, they could be pointing to the same data, which would be undefined behaviour.

Also, this may only be done with sized types, since for example, an RwData<Buffer> could point to the same Buffer as some RwData<dyn Widget>, even if dyn Widget and Buffer are “different types.

§Panics

For now, due to the inability to compary two TypeIds at compile time in stable Rust, calling this function on two RwDatas of the same type will simply panic at runtime.

However, in the future, once PartialEq is allowed in const contexts, this function will refuse to compile if the RwDatas are of the same type.

In practice, the outcome ends up being the same, since breaking that invariant results in the rejection of your conde regardless, it will just happen in a more convenient place in the future.

Source

pub fn read_and_write<'a, L: 'static, R: 'static>( &'a mut self, lhs: &'a RwData<L>, rhs: &'a RwData<R>, ) -> (&'a L, &'a mut R)

Writes to one RwData and reads from another at the same time

This can only be done when the RwDatas are of different types since, if they were of the same type, they could be pointing to the same data, which would be undefined behaviour.

Also, this may only be done with sized types, since for example, an RwData<Buffer> could point to the same Buffer as some RwData<dyn Widget>, even if dyn Widget and Buffer are “different types.

§Panics

For now, due to the inability to compary two TypeIds at compile time in stable Rust, calling this function on two RwDatas of the same type will simply panic at runtime.

However, in the future, once PartialEq is allowed in const contexts, this function will refuse to compile if the RwDatas are of the same type.

In practice, the outcome ends up being the same, since breaking that invariant results in the rejection of your conde regardless, it will just happen in a more convenient place in the future.

Source

pub fn try_write_two<'a, L: ?Sized + 'static, R: ?Sized + 'static>( &'a mut self, lhs: &'a RwData<L>, rhs: &'a RwData<R>, ) -> Option<(&'a mut L, &'a mut R)>

Tries to write to two RwData at the same time, failing if they point to the same data

Almost all the time, you will want to use Pass::write_two instead of this function, since it always returns and is checked at compile time. There are only two situations where you should consider using this function:

  • One or two of the RwDatas point to unsized types.
  • They point to the same type.

Given these two constraints however, you should still make sure that the two RwDatas don’t point to the same data.

Source

pub fn try_read_and_write<'a, L: ?Sized + 'static, R: ?Sized + 'static>( &'a mut self, lhs: &'a RwData<L>, rhs: &'a RwData<R>, ) -> Option<(&'a L, &'a mut R)>

Tries to write to one RwData and reads from another at the same time

Almost all the time, you will want to use Pass::read_and_write instead of this function, since it always returns and is checked at compile time. There are only two situations where you should consider using this function:

  • One or two of the RwDatas point to unsized types.
  • They point to the same type.

Given these two constraints however, you should still make sure that the two RwDatas don’t point to the same data.

Auto Trait Implementations§

§

impl Freeze for Pass

§

impl RefUnwindSafe for Pass

§

impl Send for Pass

§

impl Sync for Pass

§

impl Unpin for Pass

§

impl UnwindSafe for Pass

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> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
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.