serde icon indicating copy to clipboard operation
serde copied to clipboard

Is there plans for allowing async custom serialize function implementations using traits?

Open alexipeck opened this issue 1 year ago • 1 comments

I ask this on the tail end of async functions in traits being stabilized.

For context, with tokio::sync::RwLock wrapping a type, I would need the following as a custom serializer for a struct field:

mod arc_rwlock_serde {
    use serde::ser::Serializer;
    use serde::Serialize;
    use std::sync::Arc;
    use tokio::sync::RwLock;

    pub async fn serialize<S, T>(val: &Arc<RwLock<T>>, s: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
        T: Serialize,
    {
        T::serialize(&*val.read().await, s)
    }
}

#[derive(Debug, Clone, Serialize)]
#[serde(bound(serialize = "T: Serialize"))]
pub struct State<T: Clone + Serialize> {
    #[serde(with = "arc_rwlock_serde")]
    pub state: Arc<RwLock<HashMap<Uuid, T>>>,
}

Previously using a sync locking library like parking_lot, I had the following (as you can see, not much changed except for the await and library change):

mod arc_rwlock_serde {
    use serde::ser::Serializer;
    use serde::Serialize;
    use std::sync::Arc;
    use parking_lot::RwLock;

    pub async fn serialize<S, T>(val: &Arc<RwLock<T>>, s: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
        T: Serialize,
    {
        T::serialize(&*val.read(), s)
    }
}

Part of my problem is I can't even do a custom serializer without doing everything manually for the struct as there is currently no support for an async function.

alexipeck avatar Feb 04 '24 08:02 alexipeck

This is not possible unless we get an async effect system, which is years off if we'll get it at all.

The workaround for these cases is to write into a buffer and then serialize from the buffer asynchronously.

In your case that is deeply nested, you probably need to use block_on

oli-obk avatar Feb 04 '24 09:02 oli-obk