如何修改Result的JSON输出[[使用serde序列化?

问题描述 投票:0回答:1
一个简单的代码:

use serde::Serialize; #[derive(Serialize)] struct MyStruct { foo: Result<u32, String> } fn main() { let m = MyStruct { foo: Ok(43) }; let n = MyStruct { foo: Err("oh no!".into()) }; println!("{}", serde_json::to_string_pretty(&m).unwrap()); println!("{}", serde_json::to_string_pretty(&n).unwrap()); }

此输出(playground):

{ "foo": { "Ok": 43 } } { "foo": { "Err": "oh no!" } }

我可以修改序列化程序以为Result<T,E>提供自定义输出吗?我想要类似的东西:

// No "Ok" field in case of Ok(T) { "foo": 43 } // Rename "Err" to "error" in case of Err(E) { "foo": { "error": "oh no!" } }

rust serde
1个回答
3
投票
Serde attributes的功能不足以进行从默认Result序列化到所需序列的转换,因此您需要编写自定义序列化。幸运的是,它非常简单:

use serde::{Serialize, Serializer, ser::SerializeMap}; struct MyStruct { foo: Result<u32, String> } impl Serialize for MyStruct { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { let mut map = serializer.serialize_map(Some(1))?; match &self.foo { Ok(value) => map.serialize_entry("foo", &value)?, Err(error) => map.serialize_entry("foo", &MyError { error } )?, } map.end() } } // This is just used internally to get the nested error field #[derive(Serialize)] struct MyError<E> { error: E, }

© www.soinside.com 2019 - 2024. All rights reserved.