最も簡単な解決策は、Serde field attributedeserialize_with
を使用して、フィールドのカスタムシリアル化機能を設定することです。それはそれを再利用できるようにするために、独自のタイプにそれを促進する小さなステップだが、ここから
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
:
#[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
その後、生の文字列と
convert it as appropriateを得ることができます
も参照してください。
ありがとう@Shepmaster。これはまさに私が探しているものです。唯一の問題は、私がこのパニックを得るときの文字列への参照ですmsg:無効な型:文字列 "0x400"、借用文字列が必要です。 – phodina
@phodinaどちらの例も正常に実行されているので、明らかに何かを変更しました。私は心の読者ではないので、その違いは何か分かりません。 XMLデコーダが文字列スライスを提供できない場合、 'let s:String = ...'を試すことができます。 – Shepmaster
私は両方の例をプレイグラウンドと自分のPCで試しましたが、どちらもうまくいきます。この問題は、基礎となる形式をjsonからxmlに変更すると発生します。ここにコードはありますか?(遊び場にはserrate_xml_rsがありません) raw = r# " 0xDEADBEEF EtheriumTransaction>"# トランザクション:EtheriumTransaction = serde_xml_rs :: deserialize(raw.as_bytes())。unwrap(); –
phodina