2017-09-28 9 views
3

を入力し、それを与える:逆シリアル化JSON配列と、私はのように見えるJSON持っタグに

[{"range": [1, 2]}, {"range": [2, 5]}] 

配列内のオブジェクトはもちろんのrange以外の分野を持っているが、それは問題ではありませんが。

開始点と終了点が自動的に包括的か排他的かを示す2つのファントム型を持つタプルにデシリアライズすることはできますか?

これは、ファントムタイプのいくつかの種類のタプルに数値をデシリアライズすることで解決することもできます。

#[macro_use] 
extern crate serde_derive; 
extern crate serde_json; 

use std::marker::PhantomData; 

#[derive(Debug)] 
struct Inclusive; 
#[derive(Debug)] 
struct Exclusive; 

#[derive(Deserialize)] 
struct Range<S, E, V: Ord>(Option<V>, Option<V>, PhantomData<S>, PhantomData<E>); 

fn main() { 
    let data = "[1, 2]"; 
    let r: Range<Inclusive, Exclusive, i32> = serde_json::from_str(data).expect("Error"); 
    println!("Range from {:?} to {:?}", r.0, r.1); 
} 

serde_jsonPhantomDataについて無知であるように思わそして正確に私が避けしたいものである、手動Deserializerを実装することによって解決することができる大きさ4の配列を、期待するので、これは動作しません。

私は高い期待はしていませんが、おそらくこれができ、私は何かを知らないのです。

答えて

3

あなたはserdeに特定のフィールドを完全に無視させたいと思うようです。これは#[serde(skip)]で行うことができます。 Serdeはからデフォルト値を取得します。これはPhantomDataで利用可能です。

#[derive(Debug, Deserialize)] 
struct Range<S, E, V: Ord>(
    Option<V>, 
    Option<V>, 
    #[serde(skip)] PhantomData<S>, 
    #[serde(skip)] PhantomData<E>, 
); 

Playground

サイドノート(おそらく)で、あなたの種類InclusiveExclusiveは常に単位様およびないシングルトンであれば、あなたは彼らにもなりますから、それらを保持する代わりに、直接のPhantomData検討するかもしれませんゼロサイズ。

#[derive(Debug, Default)] 
struct Inclusive; 
#[derive(Debug, Default)] 
struct Exclusive; 

#[derive(Deserialize)] 
struct Range<S, E, V: Ord>(
    Option<V>, 
    Option<V>, 
    #[serde(skip)] S, 
    #[serde(skip)] E, 
); 
+0

ありがとう!素晴らしい解決策のようだ。厳密に境界の1つが 'Some'になるように' Range'コンストラクタを制約する方法はありますか? – user1685095

+0

@ user1685095それは私が信じることは、別の質問をするでしょう。列挙型の使用を検討してください。 –

関連する問題