¿Cómo puedo mutar un StorageMap cuando el valor es un enum?
Aquí está mi StorageMap:
#[pallet::storage]
#[pallet::getter(fn hotel_status)]
/// Lleva registro de qué cuentas poseen qué Kitty.
pub(super) type HotelStatus<t: config=""> = StorageMap<
_,
Twox64Concat,
T::AccountId,
Gender,
>;
Quiero usar try_mutate
para mutar el Género porque el AccountId ya existe en el mapa, o insertar una nueva entrada. Aquí está el extrínseco completo:
#[pallet::weight(0)]
pub fn activate_hotel(
origin: OriginFor<t>,
hotel: T::AccountId,
) -> DispatchResult {
let sender = ensure_signed(origin)?;
log::info!("signer ID: {:?}.", sender);
let hotel_status = <><t>>::get(&hotel);
ensure!(hotel_status == Some(Gender::Active),
<><t>>::HotelAlreadyActive);
<><t>>::try_mutate(hotel, |status| {
*status = Gender::Active;
Ok(())
}).map_err(|_| <><t>>::insert(hotel, Gender::Active))
}
El error que estoy recibiendo es:
mismatched types
expected mutable reference, found enum `pallet::Gender`
note: expected mutable reference `&mut std::option::Option<pallet::gender>`
found enum `pallet::Gender`rustc(E0308)
lib.rs(297, 14): expected mutable reference, found enum `pallet::Gender`
Los tutoriales de Substrate solo dan un ejemplo donde el valor es un vec y tratan de agregar un nuevo elemento, así que estoy perdido en cómo mutar un enum o un tipo primitivo (por ejemplo, string, número).
davy.ai
El mensaje de error indica que el cierre pasado a
try_mutate
está intentando asignar un valor astatus
de tipoGender
, que no es una referencia mutable. En cambio, el cierre debe tomar una referencia mutable astatus
, así:Tenga en cuenta que usamos el operador de desreferencia
*
para asignar el nuevo valor astatus
. Esto es necesario porquestatus
es una referencia al valor almacenado en el mapa de almacenamiento, por lo que necesitamos desreferenciarlo para acceder al valor en sí.Una vez que se arregle el cierre, podemos eliminar la llamada a
insert
dentro demap_err
, ya quetry_mutate
ya maneja el caso en que la clave no existe en el mapa.