[go: up one dir, main page]

Struct mucell::MuCell

source ·
pub struct MuCell<T: ?Sized> { /* private fields */ }
Expand description

A cell with the ability to mutate the value through an immutable reference when safe.

Implementations§

source§

impl<T> MuCell<T>

source

pub fn new(value: T) -> MuCell<T>

Creates a MuCell containing value.

§Examples
use mucell::MuCell;

let c = MuCell::new(5);
Examples found in repository?
examples/vector_munger.rs (line 59)
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
fn main() {
    // Having these cells as the values in a map is about the most common mode of usage for this
    // library that I can think of.
    let mut items = HashMap::new();
    items.insert("foo", MuCell::new(Inner::new(vec![1, 2, 3])));
    items.insert("bar", MuCell::new(Inner::new(vec![4, 5, 6])));
    items.insert("baz", MuCell::new(Inner::new(vec![7, 8, 9])));

    // foo and baz can be unborrowed, but bar can be borrowed.
    let _active_borrow = items.get("bar").unwrap().borrow();

    let item = items.get("foo").unwrap();
    // First of all, we see—can we ensure that we have the munged version, in place? If we can,
    // that will make retrieving the munged version multiple times (provided `set` is not called in
    // between) more efficient, as it will only need to do the work once. Because the
    // `Ref::map(item.borrow(), item.munged())` is operating on the Cow basis and doesn’t *need*
    // `munge` to have been called, it’s fine if this mutation doesn’t actually happen.
    item.try_mutate(|x| x.munge());

    // In this particular case, we know it’s done it.
    item.borrow().assert_munged_exists();

    // Whether it had happened or not, this part is definitely true:
    let a = Ref::map(item.borrow(), |inner| inner.munged());
    assert_eq!(&*a, [2, 3, 4]);

    // Now suppose we do the same for bar, which has been borrowed.
    let item = items.get(&"bar").unwrap();
    // This time, try_mutate will *not* do the munging.
    item.try_mutate(|x| x.munge());
    item.borrow().assert_munged_does_not_exist();

    // … but the munged() Cow is still just fine.
    let a = Ref::map(item.borrow(), |inner| inner.munged());
    assert_eq!(&*a, [5, 6, 7]);

    // With another map call and an into_inner(), we can get the value out of
    // it without cloning it all if it’s already Cow::Owned. Efficiency, yay!
    let _munged: Vec<i32> = Ref::map(a, |a| a.into_owned()).into_inner();

}
source

pub fn into_inner(self) -> T

Consumes the MuCell, returning the wrapped value.

§Examples
use mucell::MuCell;

let c = MuCell::new(5);

let five = c.into_inner();
source§

impl<T: ?Sized> MuCell<T>

source

pub fn borrow(&self) -> Ref<'_, &T>

Immutably borrows the wrapped value.

The borrow lasts until the returned Ref exits scope. Multiple immutable borrows can be taken out at the same time.

§Panics

Panics if called inside the try_mutate() mutator function. But that’s generally a nonsensical thing to do, anyway, so just be sensible and you’re OK.

Examples found in repository?
examples/vector_munger.rs (line 64)
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
fn main() {
    // Having these cells as the values in a map is about the most common mode of usage for this
    // library that I can think of.
    let mut items = HashMap::new();
    items.insert("foo", MuCell::new(Inner::new(vec![1, 2, 3])));
    items.insert("bar", MuCell::new(Inner::new(vec![4, 5, 6])));
    items.insert("baz", MuCell::new(Inner::new(vec![7, 8, 9])));

    // foo and baz can be unborrowed, but bar can be borrowed.
    let _active_borrow = items.get("bar").unwrap().borrow();

    let item = items.get("foo").unwrap();
    // First of all, we see—can we ensure that we have the munged version, in place? If we can,
    // that will make retrieving the munged version multiple times (provided `set` is not called in
    // between) more efficient, as it will only need to do the work once. Because the
    // `Ref::map(item.borrow(), item.munged())` is operating on the Cow basis and doesn’t *need*
    // `munge` to have been called, it’s fine if this mutation doesn’t actually happen.
    item.try_mutate(|x| x.munge());

    // In this particular case, we know it’s done it.
    item.borrow().assert_munged_exists();

    // Whether it had happened or not, this part is definitely true:
    let a = Ref::map(item.borrow(), |inner| inner.munged());
    assert_eq!(&*a, [2, 3, 4]);

    // Now suppose we do the same for bar, which has been borrowed.
    let item = items.get(&"bar").unwrap();
    // This time, try_mutate will *not* do the munging.
    item.try_mutate(|x| x.munge());
    item.borrow().assert_munged_does_not_exist();

    // … but the munged() Cow is still just fine.
    let a = Ref::map(item.borrow(), |inner| inner.munged());
    assert_eq!(&*a, [5, 6, 7]);

    // With another map call and an into_inner(), we can get the value out of
    // it without cloning it all if it’s already Cow::Owned. Efficiency, yay!
    let _munged: Vec<i32> = Ref::map(a, |a| a.into_owned()).into_inner();

}
source

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

Mutably borrows the wrapped value.

Unlike RefCell.borrow_mut, this method lets Rust’s type system prevent aliasing and so cannot have anything go wrong. It is also, in consequence, completely free, unlike RefCell or MuCell.borrow which all have to keep track of borrows at runtime.

source

pub fn try_mutate<F: FnOnce(&mut T)>(&self, mutator: F) -> bool

Mutate the contained object if possible.

If any immutable references produced by calling borrow() are active, this will return false, not executing the function given.

If there are no immutable references active, this will execute the mutator function and return true.

The mutator function should not touch self (not that it would really make much sense to be touching it, anyway); most notably, you may not call borrow on self inside the mutator, which includes things like the == implementation which borrow the value briefly; while calling try_mutate inside it will just return false, calling borrow will panic.

Examples found in repository?
examples/vector_munger.rs (line 72)
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
fn main() {
    // Having these cells as the values in a map is about the most common mode of usage for this
    // library that I can think of.
    let mut items = HashMap::new();
    items.insert("foo", MuCell::new(Inner::new(vec![1, 2, 3])));
    items.insert("bar", MuCell::new(Inner::new(vec![4, 5, 6])));
    items.insert("baz", MuCell::new(Inner::new(vec![7, 8, 9])));

    // foo and baz can be unborrowed, but bar can be borrowed.
    let _active_borrow = items.get("bar").unwrap().borrow();

    let item = items.get("foo").unwrap();
    // First of all, we see—can we ensure that we have the munged version, in place? If we can,
    // that will make retrieving the munged version multiple times (provided `set` is not called in
    // between) more efficient, as it will only need to do the work once. Because the
    // `Ref::map(item.borrow(), item.munged())` is operating on the Cow basis and doesn’t *need*
    // `munge` to have been called, it’s fine if this mutation doesn’t actually happen.
    item.try_mutate(|x| x.munge());

    // In this particular case, we know it’s done it.
    item.borrow().assert_munged_exists();

    // Whether it had happened or not, this part is definitely true:
    let a = Ref::map(item.borrow(), |inner| inner.munged());
    assert_eq!(&*a, [2, 3, 4]);

    // Now suppose we do the same for bar, which has been borrowed.
    let item = items.get(&"bar").unwrap();
    // This time, try_mutate will *not* do the munging.
    item.try_mutate(|x| x.munge());
    item.borrow().assert_munged_does_not_exist();

    // … but the munged() Cow is still just fine.
    let a = Ref::map(item.borrow(), |inner| inner.munged());
    assert_eq!(&*a, [5, 6, 7]);

    // With another map call and an into_inner(), we can get the value out of
    // it without cloning it all if it’s already Cow::Owned. Efficiency, yay!
    let _munged: Vec<i32> = Ref::map(a, |a| a.into_owned()).into_inner();

}

Trait Implementations§

source§

impl<T: Binary> Binary for MuCell<T>

source§

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

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

impl<T: Clone> Clone for MuCell<T>

source§

fn clone(&self) -> MuCell<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for MuCell<T>

source§

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

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

impl<T: Default> Default for MuCell<T>

source§

fn default() -> MuCell<T>

Returns the “default value” for a type. Read more
source§

impl<T: Display> Display for MuCell<T>

source§

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

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

impl<T> Hash for MuCell<T>
where T: Hash,

source§

fn hash<H: Hasher>(&self, state: &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<T: LowerExp> LowerExp for MuCell<T>

source§

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

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

impl<T: LowerHex> LowerHex for MuCell<T>

source§

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

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

impl<T: Octal> Octal for MuCell<T>

source§

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

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

impl<T: Ord> Ord for MuCell<T>

source§

fn cmp(&self, other: &MuCell<T>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<T: ?Sized + PartialEq> PartialEq for MuCell<T>

source§

fn eq(&self, other: &MuCell<T>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<T: PartialOrd> PartialOrd for MuCell<T>

source§

fn partial_cmp(&self, other: &MuCell<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

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

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

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

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

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

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

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

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl<T: Pointer> Pointer for MuCell<T>

source§

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

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

impl<T: UpperExp> UpperExp for MuCell<T>

source§

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

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

impl<T: UpperHex> UpperHex for MuCell<T>

source§

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

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

impl<T: ?Sized + Eq> Eq for MuCell<T>

source§

impl<T> Send for MuCell<T>
where T: Send + ?Sized,

Auto Trait Implementations§

§

impl<T> !Freeze for MuCell<T>

§

impl<T> !RefUnwindSafe for MuCell<T>

§

impl<T> !Sync for MuCell<T>

§

impl<T> Unpin for MuCell<T>
where T: Unpin + ?Sized,

§

impl<T> UnwindSafe for MuCell<T>
where T: UnwindSafe + ?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> CloneToUninit for T
where T: Clone,

source§

default unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. 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> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

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

§

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>,

§

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.