Один из способов приблизиться к этому - определить отдельные структуры для вашего «формата проводов», затем предоставить реализации From<>
для преобразования в форматы проводов и обратно, а затем, наконец, использовать from
и into
serde для выполните окончательные преобразования.
Реализация структур проводов и реализации From немного утомительна, но проста:
use serde::{Serialize,Deserialize};
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(from = "ResponseErrorWireFormat", into = "ResponseErrorWireFormat")]
pub struct ResponseError {
pub status: String,
pub title: String,
pub message: String,
pub trace: Option<String>,
}
#[derive(Serialize, Deserialize)]
pub struct ResponseErrorInfoWireFormat {
pub title: String,
pub message: String,
pub trace: Option<String>,
}
#[derive(Serialize, Deserialize)]
pub struct ResponseErrorWireFormat {
pub status: String,
pub info: ResponseErrorInfoWireFormat
}
impl From<ResponseErrorWireFormat> for ResponseError {
fn from(v: ResponseErrorWireFormat) -> ResponseError {
ResponseError {
status: v.status,
title: v.info.title,
message: v.info.message,
trace: v.info.trace,
}
}
}
impl From<ResponseError> for ResponseErrorWireFormat {
fn from(v: ResponseError) -> ResponseErrorWireFormat {
ResponseErrorWireFormat {
status: v.status,
info: ResponseErrorInfoWireFormat {
title: v.title,
message: v.message,
trace: v.trace,
}
}
}
}
Тогда код для использования прост:
fn main() {
let v = ResponseError {
status: "an error".to_string(),
title: "an error title".to_string(),
message: "oh my, an error!".to_string(),
trace: Some("it happened right here.".to_string()),
};
let serialized = serde_json::to_string(&v).unwrap();
println!("serialized = {}", serialized);
let deserialized: ResponseError = serde_json::from_str(&serialized).unwrap();
println!("deserialized = {:?}", deserialized);
}
Полный пример можно найти здесь