如何使用Serde进行反序列化时转换字段?

编程入门 行业动态 更新时间:2024-10-27 13:30:57
本文介绍了如何使用Serde进行反序列化时转换字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我使用Serde将具有十六进制值 0x400 的XML文件反序列化为一个字符串,我需要将它转换为值 1024 作为 u32 。

我是否需要实现 Visitor trait,这样我就可以将0x分开,然后从基本16解码400到基本10?如果是这样,我该怎么做,以便10个基本整数的反序列化保持不变?

解决方案 deserialize_with 属性

最简单的解决方案是使用 Serde字段属性 deserialize_with 为您的字段设置自定义序列化功能。然后,您可以获取原始字符串并将其转换为适当的:

extern crate serde; #[macro_use] extern crate serde_derive; extern crate serde_json; 使用serde :: {Deserialize,Deserializer}; 使用serde :: de :: Error; $ b $ [b] [b] struct EtheriumTransaction {#[serde(deserialize_with =from_hex)] account:u64,// hex amount:u64,//十进制} fn from_hex<'de,D>(解串器:D) - >结果< u64,D ::错误> 其中 D:反序列化器< de>, { let s:& str =反序列化::反序列化(反序列化器)? //比这个更好的十六进制解码u64 :: from_str_radix(& s [2 ..],16).map_err(D :: Error :: custom)} fn main(){ let raw = r#{account:0xDEADBEEF,amount:100}#; let transaction:EtheriumTransaction = serde_json :: from_str(raw).expect(Could not derserialize); assert_eq!(transaction.amount,100); assert_eq!(transaction.account,0xDEAD_BEEF); }

playground $ b 实现 serde :: Deserialize 从这里开始,将它推广到自己的类型以允许重用它是一小步:

#[derive(Debug,Deserialize)] struct EtheriumTransaction { account:Account,// hex amount:u64,// decimal $ b $#[derive(Debug,PartialEq)] struct Account(u64); impl<'de>反序列化<去>用于帐户{ fn反序列化< D>(反序列化器:D) - >结果< Self,D :: Error> 其中 D:反序列化器< de>, { let s:& str =反序列化::反序列化(反序列化器)? //比这个更好的十六进制解码u64 :: from_str_radix(& s [2 ..],16) .map(Account) .map_err(D: :Error :: custom)} }

playground

请注意,使用任何其他现有的Serde实现来解码。在这里,我们解码为一个字符串片段( let s:& str = Deserialize :: deserialize(deserializer)?)。

此方法允许您添加或删除字段,因为内部反序列化类型可以根据需要进行任何操作。

另请参阅:

  • 如何在使用Serde序列化期间转换字段?

I'm using Serde to deserialize an XML file which has the hex value 0x400 as a string and I need to convert it to the value 1024 as a u32.

Do I need to implement the Visitor trait so that I separate 0x and then decode 400 from base 16 to base 10? If so, how do I do that so that deserialization for base 10 integers remains intact?

解决方案

The deserialize_with attribute

The easiest solution is to use the Serde field attribute deserialize_with to set a custom serialization function for your field. You then can get the raw string and convert it as appropriate:

extern crate serde; #[macro_use] extern crate serde_derive; extern crate serde_json; use serde::{Deserialize, Deserializer}; use serde::de::Error; #[derive(Debug, Deserialize)] struct EtheriumTransaction { #[serde(deserialize_with = "from_hex")] account: u64, // hex amount: u64, // decimal } fn from_hex<'de, D>(deserializer: D) -> Result<u64, D::Error> where D: Deserializer<'de>, { let s: &str = Deserialize::deserialize(deserializer)?; // do better hex decoding than this u64::from_str_radix(&s[2..], 16).map_err(D::Error::custom) } fn main() { let raw = r#"{"account": "0xDEADBEEF", "amount": 100}"#; let transaction: EtheriumTransaction = serde_json::from_str(raw).expect("Couldn't derserialize"); assert_eq!(transaction.amount, 100); assert_eq!(transaction.account, 0xDEAD_BEEF); }

playground

Implement serde::Deserialize

From here, it's a tiny step to promoting it to your own type to allow reusing it:

#[derive(Debug, Deserialize)] struct EtheriumTransaction { account: Account, // hex amount: u64, // decimal } #[derive(Debug, PartialEq)] struct Account(u64); impl<'de> Deserialize<'de> for Account { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { let s: &str = Deserialize::deserialize(deserializer)?; // do better hex decoding than this u64::from_str_radix(&s[2..], 16) .map(Account) .map_err(D::Error::custom) } }

playground

Note how this can use any other existing Serde implementation to decode. Here, we decode to a string slice (let s: &str = Deserialize::deserialize(deserializer)?).

This method allows you to also add or remove fields as the "inner" deserialized type can do basically whatever it wants.

See also:

  • How to transform fields during serialization using Serde?

更多推荐

如何使用Serde进行反序列化时转换字段?

本文发布于:2023-08-04 05:53:16,感谢您对本站的认可!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:字段   如何使用   序列化   Serde

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!