Struct Holder

Source
pub struct Holder<V, BI, BM> { /* private fields */ }
Expand description

A type that holds a value and allows us borrow the value.

When you want to borrow inner value you can call Holder::borrow or Holder::borrow_mut. They return the inner value wrapped in Borrowed which tracks borrow status.

Multiple immutable borrowing is allowed, but mutable borrowing is exclusive. If this struct is dropped while any borrowed value is alive, it causes panic. You can check it out using Holder::borrow_count to see there’s any borrowed value.

§Features

Borrow check is enabled if and only if check feature is enabled. Otherwise, this struct does nothing special.

Implementations§

Source§

impl<V, BI, BM> Holder<V, BI, BM>

Source

pub unsafe fn new<'v>( value: V, fn_imm: fn(&'v V) -> BI, fn_mut: fn(&'v mut V) -> BM, ) -> Self

Creates a Holder with the given value.

Holder checks borrow rule at runtime by enabled feature check. But it requires additional operations, so that if you are confident, you can use the Holder without the borrow check.

  • fn_imm - Function that borrows the value and returns borrowed immutable value.
  • fn_mut - Function that borrows the value and returns borrowed mutable value.
§Safety

Holder disables Rust default borrow checker. Borrow rule is not checked even if the fn_imm and fn_mut return references to the inner value. However, Holder checks the borrow rule at runtime by enabled feature check. If the feature is not enabled, this function is unsafe due to the disabled runtime borrow check.

If the fn_imm and fn_mut returns static type instead of reference, it’s safe regardless of enabling the feature because they don’t need borrow check.

§Examples
use my_ecs::ds::Holder;

let mut holder: Holder<i32, &i32, &mut i32> = unsafe {
    Holder::new(0, |v| v, |v| v)
};
let a = holder.borrow_mut().unwrap();
holder.borrow_mut().unwrap(); // No panic without `check` feature
println!("{a:?}");
Source

pub fn into_value(self) -> V

Unwraps the holder and returns inner value.

§Examples
use my_ecs::ds::Holder;

let holder = unsafe { Holder::new(0, |v| v, |v| v) };
assert_eq!(holder.into_value(), 0);
Source

pub fn get_fn_imm(&self) -> fn(&V) -> BI

Returns immutable borrow function that you inserted at Holder::new.

Source

pub fn get_fn_mut(&self) -> fn(&mut V) -> BM

Returns mutable borrow function that you inserted at Holder::new.

Source

pub fn borrow(&self) -> BorrowResult<BI>

Borrows inner value.

If check feature is enabled, runtime borrow checker works and blocks try borrowing value after mutable borrow.

§Examples
use my_ecs::ds::Holder;

let holder = unsafe { Holder::new(0, |v| v, |v| v) };
assert_eq!(*holder.borrow().unwrap(), &0);
Source

pub fn borrow_mut(&mut self) -> BorrowResult<BM>

Borrows inner value mutably.

If check feature is enabled, runtime borrow checker works and blocks try borrowing value after mutable or immutable borrow.

§Examples
use my_ecs::ds::Holder;

let mut holder = unsafe { Holder::new(0, |v| v, |v| v) };
**holder.borrow_mut().unwrap() = 1;
assert_eq!(*holder.borrow().unwrap(), &1);
Source

pub fn get(&self) -> BorrowResult<&V>

Returns shared reference to the inner value without calling immutable borrow function that you inserted at Holder::new.

If check feature is enabled, runtime borrow checker works and blocks try borrowing value after mutable borrow.

§Examples
use my_ecs::ds::Holder;

let holder = unsafe { Holder::new(0, |v| *v + 1, |v| *v + 1) };
let value = holder.get().unwrap();
assert_eq!(*value, &0); // Due to bypassed borrow function.
Source

pub fn get_mut(&mut self) -> BorrowResult<&mut V>

Returns mutable reference to the inner value without calling mutable borrow function that you inserted at Holder::new.

If check feature is enabled, runtime borrow checker works and blocks try borrowing value after mutable or immutable borrow.

§Examples
use my_ecs::ds::Holder;

let mut holder = unsafe { Holder::new(0, |v| *v + 1, |v| *v + 1) };
let value = holder.get_mut().unwrap();
assert_eq!(*value, &mut 0); // Due to bypassed borrow function.
Source

pub unsafe fn get_unchecked(&self) -> &V

Returns shared reference to inner value without borrow check.

§Safety

Undefined behavior if exclusive borrow happened before.

§Examples
use my_ecs::ds::Holder;

let holder = unsafe { Holder::new(0, |v| v, |v| v) };
let value = unsafe { holder.get_unchecked() };
assert_eq!(value, &0);
Source

pub unsafe fn get_unchecked_mut(&mut self) -> &mut V

Returns mutable reference to inner value without borrow check.

§Safety

Undefined behavior if exclusive borrow happened before.

§Examples
use my_ecs::ds::Holder;

let mut holder = unsafe { Holder::new(0, |v| v, |v| v) };
let value = unsafe { holder.get_unchecked_mut() };
assert_eq!(value, &0);
Source

pub fn borrow_count(&self) -> i32

Returns current reference count.

Returning reference count will be

  • Greater than zero meaning there exist immutable borrow at the time.
  • Lesser than zero meaning there exist mutable borrow at the time.
  • Zero meaning no borrow at the time or check feature is disabled.

Trait Implementations§

Source§

impl<V: Debug, BI: Debug, BM: Debug> Debug for Holder<V, BI, BM>

Source§

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

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

impl<V, BI, BM> Drop for Holder<V, BI, BM>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<V, BI, BM> Freeze for Holder<V, BI, BM>
where V: Freeze,

§

impl<V, BI, BM> RefUnwindSafe for Holder<V, BI, BM>

§

impl<V, BI, BM> Send for Holder<V, BI, BM>
where V: Send, BI: Send, BM: Send,

§

impl<V, BI, BM> Sync for Holder<V, BI, BM>
where V: Sync, BI: Sync, BM: Sync,

§

impl<V, BI, BM> Unpin for Holder<V, BI, BM>
where V: Unpin, BI: Unpin, BM: Unpin,

§

impl<V, BI, BM> UnwindSafe for Holder<V, BI, BM>
where V: UnwindSafe, BI: UnwindSafe, BM: UnwindSafe,

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
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.