#stateful deserialization

1 messages · Page 1 of 1 (latest)

floral elk
#

i have a wrapper type that basically deserializes a Response only once do avoid deserializing it over and over again

/// Wrapper type for [`Response`] that can hold deserialized values too
#[derive(Debug)]
pub enum MaybeDeserialized<T> {
    /// Response hasn't been deserialized yet
    Response(Response<T>),
    /// Response is being deserialized
    ///
    /// This is a marker type that should be unreachable
    Deserializing,
    /// Response has been deserialized
    Deserialized(T),
}

impl<T: DeserializeOwned + Unpin + Send> MaybeDeserialized<T> {
    /// Return the deserialized model
    ///
    /// Deserializes the model if it hasn't been deserialized yet, this method
    /// is otherwise actually sync
    ///
    /// # Errors
    ///
    /// Returns [`Error::DeserializeBody`] if deserializing the type fails
    pub async fn model(&mut self) -> Result<&T, Error> {
        match self {
            Self::Response(_) => {
                let self_owned = mem::replace(self, Self::Deserializing);

                let Self::Response(response) = self_owned else {
                    unreachable!();
                };

                let model = response.model().await?;
                *self = Self::Deserialized(model);

                let Self::Deserialized(model_ref) = self else {
                    unreachable!();
                };

                Ok(model_ref)
            }
            Self::Deserializing => unreachable!(),
            Self::Deserialized(model) => Ok(model),
        }
    }
}``` maybe we could have something like this in twilight itself? there are cases where you only sometimes need to deserialize a response but because they're different types you either save `Response<T>` and deserialize every time or save `T` and always deserialize
mild badger
#

This looks like sugaring that shouldn't be in twilight in my view (I also don't really see the usecase, you generally shouldn't have a need to store the response. Just deserialize it once lol)

floral elk
#

what if you only have to deserialize sometimes

novel coral
#

The above code caches the deserialization so it would not be useful if deserialization is only needed for some requests (then you should instead not deserialize at all)

floral elk
#

unless you call model it wont be deserialized

#

and if you call model multiple times itll only be deserialized once

novel coral
#

I don't think it'd be the end of the world to put it in twilight-util if you have a use for it

floral elk
#

could do that too but under what feature flag