Skip to content

Feature Request: Add owned version of SerializeAsWrap #827

@Leo1003

Description

@Leo1003

SerializeAsWrap is a convenient adapter which provide Serialize implementation over SerializeAs.

However, SerializeAsWrap only store the reference to the data, which makes it not able to return data wrapped with specific SerializeAs impl.

Given an example actix-web api:

#[get("/data")]
pub async fn get_data() -> AppResult<impl Responder> {
    let data = get_data().await?;
    Ok(Json(data))
}

#[get("/data_detailed")]
pub async fn get_data_detailed() -> AppResult<impl Responder> {
    let data = get_data().await?;
    Ok(Json(SerializeAsWrap::<MyData, Detailed>::new(&data)))
}

The above code cannot be compiled since SerializeAsWrap doesn't owns the data.

By adding an owned version of SerializeAsWrap can resolve the above issues:

pub struct SerializeAsWrapOwned<T, U> {
    value: T,
    _phantom: std::marker::PhantomData<U>,
}

impl<T, U> SerializeAsWrapOwned<T, U> {
    pub fn new(value: T) -> Self {
        Self {
            value,
            _phantom: std::marker::PhantomData,
        }
    }

    pub fn into_inner(self) -> T {
        self.value
    }
}

impl<T, U> AsRef<T> for SerializeAsWrapOwned<T, U> {
    fn as_ref(&self) -> &T {
        &self.value
    }
}

impl<T, U> AsMut<T> for SerializeAsWrapOwned<T, U> {
    fn as_mut(&mut self) -> &mut T {
        &mut self.value
    }
}

impl<T, U> serde::Serialize for SerializeAsWrapOwned<T, U>
where
    U: serde_with::SerializeAs<T>,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        U::serialize_as(&self.value, serializer)
    }
}

impl<T, U> From<T> for SerializeAsWrapOwned<T, U> {
    fn from(value: T) -> Self {
        Self::new(value)
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions