message: Add ValueOfMut
  Summary: An alternative to ValueOf that lets you grab mutable values.
diff: use crate::values::{ComplexValue, Heap, Value};
  use gazebo::cell::ARef;
  -use std::{cell::RefMut, ops::Deref};
  +use std::{cell::RefMut, marker::PhantomData, ops::Deref};
  /// How to convert a [`Value`] to a Rust type. Required for all arguments in a [`#[starlark_module]`](macro@starlark_module) definition.
  pub trait UnpackValue<'v>: Sized {
  @@ -83,6 +83,58 @@ impl<'v, T: FromValue<'v>> UnpackValue<'v> for ARef<'v, T> {
  }
  }
  +/// A wrapper around a mutable value that implements the [`UnpackValue`] trait,
  +/// allowing it to be used as an argument to [`#[starlark_module]`](macro@starlark_module)
  +/// defined functions.
  +///
  +/// The [`UnpackValue`] implementation validates that the type is correct, but not that
  +/// the value is mutable. The subsequet [`get_ref_mut`](ValueOfMut::get_ref_mut)
  +/// checks the value is actually mutable.
  +#[derive(Debug)]
  +pub struct ValueOfMut<'v, T: ComplexValue<'v>> {
  + // We can't expose this directly, since the user might change it,
  + // negating the check we did when constructing
  + value: Value<'v>,
  + phantom: PhantomData<T>,
  +}
  +
  +impl<'v, T: ComplexValue<'v>> UnpackValue<'v> for ValueOfMut<'v, T> {
  + fn unpack_value(value: Value<'v>, _heap: &'v Heap) -> Option<Self> {
  + if value.get_aref().as_dyn_any().is::<T>() {
  + Some(ValueOfMut {
  + value,
  + phantom: PhantomData::default(),
  + })
  + } else {
  + None
  + }
  + }
  +}
  +
  +impl<'v, T: ComplexValue<'v>> ValueOfMut<'v, T> {
  + /// Get the underlying [`Value`] on the original heap.
  + pub fn value(&self) -> Value<'v> {
  + self.value
  + }
  +
  + pub fn get_aref(&self) -> ARef<'v, T> {
  + // The `unwrap` won't fail because we checked at construction time.
  + let vref = self.value.get_aref();
  + ARef::map(vref, |any| any.as_dyn_any().downcast_ref::<T>().unwrap())
  + }
  +
  + /// Get the value for mutation. Note that while the value is held for mutation,
  + /// any other operation that accesses the value for non-mutable purposes
  + /// might panic, so try and scope access as tightly as possible.
  + pub fn get_ref_mut(&self, heap: &'v Heap) -> anyhow::Result<RefMut<'v, T>> {
  + let vref = self.value.get_ref_mut(heap)?;
  + Ok(RefMut::map(vref, |any| {
  + // The `unwrap` won't fail because we checked at construction time.
  + any.as_dyn_any_mut().downcast_mut::<T>().unwrap()
  + }))
  + }
  +}
  +
  impl<'v, T: ComplexValue<'v>> UnpackValue<'v> for RefMut<'v, T> {
  fn unpack_value(value: Value<'v>, heap: &'v Heap) -> Option<Self> {
  value.downcast_mut(heap).ok()?
  