From b8396b9cc0bd5f40f1b5ca51484c7b515b7d4493 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Thu, 27 Jan 2022 16:05:22 +0100 Subject: [PATCH] client-api: Fix response serde for get[_latest]_backup --- .../src/r0/backup/get_backup.rs | 64 ++++++++++++++++++- .../src/r0/backup/get_latest_backup.rs | 45 ++++++++++++- 2 files changed, 106 insertions(+), 3 deletions(-) diff --git a/crates/ruma-client-api/src/r0/backup/get_backup.rs b/crates/ruma-client-api/src/r0/backup/get_backup.rs index d27681cc..ce5c6361 100644 --- a/crates/ruma-client-api/src/r0/backup/get_backup.rs +++ b/crates/ruma-client-api/src/r0/backup/get_backup.rs @@ -3,6 +3,8 @@ use js_int::UInt; use ruma_api::ruma_api; use ruma_serde::Raw; +use serde::{ser, Deserialize, Deserializer, Serialize}; +use serde_json::value::{to_raw_value as to_raw_json_value, RawValue as RawJsonValue}; use super::BackupAlgorithm; @@ -22,9 +24,9 @@ ruma_api! { pub version: &'a str, } + #[ruma_api(manual_body_serde)] response: { /// The algorithm used for storing backups. - #[serde(flatten)] pub algorithm: Raw, /// The number of keys stored in the backup. @@ -61,3 +63,63 @@ impl Response { Self { algorithm, count, etag, version } } } + +#[derive(Deserialize)] +pub(super) struct ResponseBodyRepr { + pub algorithm: Box, + pub auth_data: Box, + pub count: UInt, + pub etag: String, + pub version: String, +} + +#[derive(Serialize)] +pub(super) struct RefResponseBodyRepr<'a> { + pub algorithm: &'a RawJsonValue, + pub auth_data: &'a RawJsonValue, + pub count: UInt, + pub etag: &'a str, + pub version: &'a str, +} + +#[derive(Deserialize, Serialize)] +pub(super) struct AlgorithmWithData { + pub algorithm: Box, + pub auth_data: Box, +} + +impl<'de> Deserialize<'de> for ResponseBody { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let ResponseBodyRepr { algorithm, auth_data, count, etag, version } = + ResponseBodyRepr::deserialize(deserializer)?; + + let algorithm = + Raw::from_json(to_raw_json_value(&AlgorithmWithData { algorithm, auth_data }).unwrap()); + + Ok(Self { algorithm, count, etag, version }) + } +} + +impl Serialize for ResponseBody { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let ResponseBody { algorithm, count, etag, version } = self; + let AlgorithmWithData { algorithm, auth_data } = + algorithm.deserialize_as().map_err(ser::Error::custom)?; + + let repr = RefResponseBodyRepr { + algorithm: &algorithm, + auth_data: &auth_data, + count: *count, + etag, + version, + }; + + repr.serialize(serializer) + } +} diff --git a/crates/ruma-client-api/src/r0/backup/get_latest_backup.rs b/crates/ruma-client-api/src/r0/backup/get_latest_backup.rs index 3a0d9124..b8c80bc2 100644 --- a/crates/ruma-client-api/src/r0/backup/get_latest_backup.rs +++ b/crates/ruma-client-api/src/r0/backup/get_latest_backup.rs @@ -3,8 +3,13 @@ use js_int::UInt; use ruma_api::ruma_api; use ruma_serde::Raw; +use serde::{ser, Deserialize, Deserializer, Serialize}; +use serde_json::value::to_raw_value as to_raw_json_value; -use super::BackupAlgorithm; +use super::{ + get_backup::{AlgorithmWithData, RefResponseBodyRepr, ResponseBodyRepr}, + BackupAlgorithm, +}; ruma_api! { metadata: { @@ -19,9 +24,9 @@ ruma_api! { #[derive(Default)] request: {} + #[ruma_api(manual_body_serde)] response: { /// The algorithm used for storing backups. - #[serde(flatten)] pub algorithm: Raw, /// The number of keys stored in the backup. @@ -58,3 +63,39 @@ impl Response { Self { algorithm, count, etag, version } } } + +impl<'de> Deserialize<'de> for ResponseBody { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let ResponseBodyRepr { algorithm, auth_data, count, etag, version } = + ResponseBodyRepr::deserialize(deserializer)?; + + let algorithm = + Raw::from_json(to_raw_json_value(&AlgorithmWithData { algorithm, auth_data }).unwrap()); + + Ok(Self { algorithm, count, etag, version }) + } +} + +impl Serialize for ResponseBody { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let ResponseBody { algorithm, count, etag, version } = self; + let AlgorithmWithData { algorithm, auth_data } = + algorithm.deserialize_as().map_err(ser::Error::custom)?; + + let repr = RefResponseBodyRepr { + algorithm: &algorithm, + auth_data: &auth_data, + count: *count, + etag, + version, + }; + + repr.serialize(serializer) + } +}