2016-05-18 9 views
1

は、私のような構造体があります。structの一部に(RustcEncodable)を派生させることは可能ですか?

struct S { 
    data: i32, 
    fun: Box<Fn()>, 
} 

をし、エンコーダを使用してデータの一部をシリアル化したいと思います。行うには、私は

#[derive(RustcEncodable, RustcDecodable)] 
struct S { 
    data: i32, 
    fun: Box<Fn()>, 
} 

ようrustc_serializeを使用し、その特性を引き出すという問題は、それが機能だとしてfunをシリアル化することができないということです。これは、平文dataフィールドのみをシリアル化したいので、これは問題ありません。それを行う方法はありますか?

実際の使用例のdataフィールドも構造体で、Fnを持つことができますので、構造体を2つに分割することはできません。

答えて

2

短い答えは「いいえ」です。 rustc-serialize crate は、DecodableまたはEncodableのような自動化された形質のインプリメンテーションに対してそのレベルの制御を提供しません。

これを行うには、あなたはそれらを自分で実装する必要があります:あなたは、シリアル化をrustcするために結ばれていない場合は

extern crate rustc_serialize; 

use rustc_serialize::{Encodable, Encoder}; 
use rustc_serialize::json; 

struct S { 
    data: i32, 
    fun: Box<Fn()>, 
} 

impl Encodable for S { 
    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { 
     s.emit_struct("S", 1, |s| { 
      s.emit_struct_field("data", 0, |s| { 
       s.emit_i32(self.data) 
      }) 
     }) 
    } 
} 

fn main() { 
    let thing = S { data: 42, fun: Box::new(|| println!("I am a function")) }; 
    let json = json::encode(&thing).expect("Couldn't encode"); 
    println!("{}", json); 
    (thing.fun)(); 
} 

、あなたが#[serde(skip_serializing)]#[serde(skip_deserializing)]注釈を提供していますserdeに興味があるかもしれません。技術的に、#[derive(RustcEncodable, RustcDecodable)]コンパイラによって提供される:


。このため、接頭辞はRustcです。それは削除されるが、コンパイラプラグインの安定したサポートを待っている醜い疣贅です。

2

Shepmaster's answerは、RustcEncodable溶液を与えます。完全を期すため、ここでは同等Serdeコードです:

#![feature(custom_derive, plugin)] 
#![plugin(serde_macros)] 

extern crate serde_json; 

#[derive(Serialize, Deserialize)] 
struct S { 
    data: i32, 
    #[serde(skip_serializing, skip_deserializing, default="empty_fun")] 
    fun: Box<Fn()>, 
} 

fn empty_fun() -> Box<Fn()> { 
    Box::new(|| {}) 
} 

fn main() { 
    let s = S { data: 42, fun: Box::new(|| println!("I am a function")) }; 

    // prints {"data":42} 
    println!("{}", serde_json::to_string(&s).unwrap()); 
} 

skip_serializing属性は、構造体をシリアル化するとき、フィールドを無視することを意味します。同様に、skip_deserializing属性は、デシリアライズ時にフィールドを無視することを意味します。

default属性は、デシリアライズ時にフィールドに使用する値を指定します。 std::default::Defaultを実装するフィールドは、SerdeがDefault::default()の値を使用できるため、これを必要としません。

関連する問題