Rust Json batch processing overrides responsibilities

I am exploring Json serialization in Rust, specifically how to serialize Rust objects for Json.

I currently see 3 methods for converting an instance of a structure to Json:

  • Obtaining an encoded attribute

  • Manual implementation of the ToJson trait

  • Manual implementation of an encoded attribute

The code below illustrates all 3 approaches:

extern crate serialize; use serialize::{Encoder, Encodable, json}; use serialize::json::{Json, ToJson}; use std::collections::TreeMap; fn main() { let document = Document::new(); let word_document = WordDocument::new(); println!("1. Deriving `Encodable`: {}", json::encode(&document)); println!("2. Manually implementing `ToJson` trait: {}", document.to_json()); println!("3. Manually implementing `Encodable` trait: {}", json::encode(&word_document)); } #[deriving(Encodable)] struct Document<'a> { metadata: Vec<(&'a str, &'a str)> } impl<'a> Document<'a> { fn new() -> Document<'a> { let metadata = vec!(("Title", "Untitled Document 1")); Document {metadata: metadata} } } impl<'a> ToJson for Document<'a> { fn to_json(&self) -> Json { let mut tm = TreeMap::new(); for &(ref mk, ref mv) in self.metadata.iter() { tm.insert(mk.to_string(), mv.to_string().to_json()); } json::Object(tm) } } struct WordDocument<'a> { metadata: Vec<(&'a str, &'a str)> } impl<'a> WordDocument<'a> { fn new() -> WordDocument<'a> { let metadata = vec!(("Title", "Untitled Word Document 1")); WordDocument {metadata: metadata} } } impl<'a, E, S: Encoder<E>> Encodable<S, E> for WordDocument<'a> { fn encode(&self, s: &mut S) -> Result<(), E> { s.emit_map(self.metadata.len(), |e| { let mut i = 0; for &(ref key, ref val) in self.metadata.iter() { try!(e.emit_map_elt_key(i, |e| key.encode(e))); try!(e.emit_map_elt_val(i, |e| val.encode(e))); i += 1; } Ok(()) }) } } 

Rusty Playpen: http://is.gd/r7cYmE

Results:

 1. Deriving `Encodable`: {"metadata":[["Title","Untitled Document 1"]]} 2. Manually implementing `ToJson` trait: {"Title":"Untitled Document 1"} 3. Manually implementing `Encodable` trait: {"Title":"Untitled Word Document 1"} 

The first method is fully automatic, but does not provide sufficient flexibility. The second and third achieve the same level of flexibility by specifying a manual serialization process. In my case, I want the document metadata to be serialized as an object, and not as an array (this is what the implementation gives me).

Questions

  • Why are there methods 2 and 3? I do not understand the reason for the overlap between them. I expect that there is only one automatic (output) serialization method and one manual.
  • If I need manual serialization, which method to choose and why?

  • Do I believe that method 2 will build in memory (

    ) an enumerated number of Json (besides the structure itself) and is worse suited for large documents (several megabytes), while method 3 is streaming and safe for large documents?
  • Why does stdlib rust use method 3 even for primitives but not use method 2 internally?

+7
json serialization rust
source share
1 answer

Why are there methods 2 and 3? I do not understand the reason for the overlap between them. I expect that there is only one automatic (output) serialization method and one manual.

Method 2 ( ToJson ) is specific for JSON encoding. It returns JSON objects instead of writing to the stream. One use case is mapping to user views - see this example in the documentation.

Method 3 ( Encodable implementation) must exist for method 1 to work.

Do I correctly assume that method 2 will create Json correspondence in memory (in addition to the structure itself) and is less suitable for large documents (several megabytes), and method 3 will be streaming and safe for large documents?

Yes. ToJson creates a nested Json enumeration of the entire object, and Encodable Writer stream.

If I need manual serialization, which method to choose and why?

Why does stdlib rust use method 3 even for primitives but not use method 2 internally?

You must use Encodable . It is not specific to the JSON format, does not use an intermediate representation (therefore, it can be streamed rather than stored in memory) and should continue to work with new formats added to the library.

+4
source share

All Articles