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

Rust 如何在使用Serde反序列化期间转换字段?,rust,hex,serde,Rust,Hex,Serde,我正在使用Serde反序列化一个XML文件,该文件的十六进制值0x400为字符串,我需要将其转换为1024值u32 我是否需要实现Visitor特性,以便将0x分开,然后将400从基数16解码到基数10?如果是这样,我该如何做才能使以10为基数的整数的反序列化保持不变?使用属性的反序列化\u 最简单的解决方案是使用反序列化_和为字段设置自定义序列化函数。然后,您可以获取原始字符串并执行以下操作: 此方法还允许您添加或删除字段,因为“内部”反序列化类型基本上可以做任何它想做的事情 另见: 使

我正在使用Serde反序列化一个XML文件,该文件的十六进制值
0x400
为字符串,我需要将其转换为
1024
u32

我是否需要实现
Visitor
特性,以便将0x分开,然后将400从基数16解码到基数10?如果是这样,我该如何做才能使以10为基数的整数的反序列化保持不变?

使用属性的
反序列化\u
最简单的解决方案是使用
反序列化_和为字段设置自定义序列化函数。然后,您可以获取原始字符串并执行以下操作:

此方法还允许您添加或删除字段,因为“内部”反序列化类型基本上可以做任何它想做的事情

另见:

使用属性反序列化 最简单的解决方案是使用反序列化_和为字段设置自定义序列化函数。然后,您可以获取原始字符串并执行以下操作:

此方法还允许您添加或删除字段,因为“内部”反序列化类型基本上可以做任何它想做的事情

另见:


谢谢@Shepmaster。这正是我要找的。唯一的问题是当我得到这个紧急消息时对字符串的引用:无效类型:字符串“0x400”,应该是借用的字符串。@phodina我的两个示例都成功运行了,所以很明显你改变了什么。我不是一个读心术的人,所以我不知道有什么区别。如果XML解码器无法提供字符串片段,您可以尝试
let s:String=…
。我在游乐场和我的电脑上都尝试过这两个示例,它们都可以工作。当我将底层格式从json更改为xml时,问题就出现了。下面是代码(Playerd misses板条箱serde_xml_rs)let raw=r#“0xDEADBEEF100”#;let transaction:EtheriumTransaction=serde_xml_rs::反序列化(原始.as_字节()).unwrap()@是的,看来切换到
let s:String
很有效。谢谢@Shepmaster。这正是我要找的。唯一的问题是当我得到这个紧急消息时对字符串的引用:无效类型:字符串“0x400”,应该是借用的字符串。@phodina我的两个示例都成功运行了,所以很明显你改变了什么。我不是一个读心术的人,所以我不知道有什么区别。如果XML解码器无法提供字符串片段,您可以尝试
let s:String=…
。我在游乐场和我的电脑上都尝试过这两个示例,它们都可以工作。当我将底层格式从json更改为xml时,问题就出现了。下面是代码(Playerd misses板条箱serde_xml_rs)let raw=r#“0xDEADBEEF100”#;let transaction:EtheriumTransaction=serde_xml_rs::反序列化(原始.as_字节()).unwrap()@phodina是的,似乎切换到
let s:String
有效。
use serde::{de::Error, Deserialize, Deserializer}; // 1.0.94
use serde_json; // 1.0.40

#[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);
}
#[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)
    }
}