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>
impl<V, BI, BM> Holder<V, BI, BM>
Sourcepub unsafe fn new<'v>(
value: V,
fn_imm: fn(&'v V) -> BI,
fn_mut: fn(&'v mut V) -> BM,
) -> Self
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:?}");Sourcepub fn into_value(self) -> V
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);Sourcepub fn get_fn_imm(&self) -> fn(&V) -> BI
pub fn get_fn_imm(&self) -> fn(&V) -> BI
Returns immutable borrow function that you inserted at Holder::new.
Sourcepub fn get_fn_mut(&self) -> fn(&mut V) -> BM
pub fn get_fn_mut(&self) -> fn(&mut V) -> BM
Returns mutable borrow function that you inserted at Holder::new.
Sourcepub fn borrow(&self) -> BorrowResult<BI>
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);Sourcepub fn borrow_mut(&mut self) -> BorrowResult<BM>
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);Sourcepub fn get(&self) -> BorrowResult<&V>
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.Sourcepub fn get_mut(&mut self) -> BorrowResult<&mut V>
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.Sourcepub unsafe fn get_unchecked(&self) -> &V
pub unsafe fn get_unchecked(&self) -> &V
Sourcepub unsafe fn get_unchecked_mut(&mut self) -> &mut V
pub unsafe fn get_unchecked_mut(&mut self) -> &mut V
Sourcepub fn borrow_count(&self) -> i32
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
checkfeature is disabled.
Trait Implementations§
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>
impl<V, BI, BM> Sync for Holder<V, BI, BM>
impl<V, BI, BM> Unpin for Holder<V, BI, BM>
impl<V, BI, BM> UnwindSafe for Holder<V, BI, BM>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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