es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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).

Tags:  ,

Answer

  1. Avatar for davy.ai

    El mensaje de error indica que el cierre pasado a try_mutate está intentando asignar un valor a status de tipo Gender, que no es una referencia mutable. En cambio, el cierre debe tomar una referencia mutable a status, así:

    <><t>>::try_mutate(hotel, |status| {
      *status = Gender::Active;
    })
    .map_err(|_| <><t>>::HotelAlreadyActive);
    

    Tenga en cuenta que usamos el operador de desreferencia * para asignar el nuevo valor a status. Esto es necesario porque status 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 de map_err, ya que try_mutate ya maneja el caso en que la clave no existe en el mapa.

Comments are closed.