title: Rust Json serialization overlapping responsibilities
body: <p>I'm learning Json serialization in Rust, in particular, how to serialize Rust objects to Json.</p>
  
  <p>Currently I see 3 methods of converting an instance of a struct to Json:</p>
  
  <ol>
  <li><p>Deriving Encodable trait </p></li>
  <li><p>Manual implementation of ToJson trait</p></li>
  <li><p>Manual implementation of Encodable trait</p></li>
  </ol>
  
  <p>Below code illustrates all 3 approaches:</p>
  
  <pre><code>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(&amp;document));
    println!("2. Manually implementing `ToJson` trait: {}", document.to_json());
    println!("3. Manually implementing `Encodable` trait: {}", json::encode(&amp;word_document));
  }
  
  #[deriving(Encodable)]
  struct Document&lt;'a&gt; {
    metadata: Vec&lt;(&amp;'a str, &amp;'a str)&gt;
  }
  
  impl&lt;'a&gt; Document&lt;'a&gt; {
    fn new() -&gt; Document&lt;'a&gt; {
      let metadata = vec!(("Title", "Untitled Document 1"));
      Document {metadata: metadata}
    }
  }
  
  impl&lt;'a&gt; ToJson for Document&lt;'a&gt; {
    fn to_json(&amp;self) -&gt; Json {
      let mut tm = TreeMap::new();
      for &amp;(ref mk, ref mv) in self.metadata.iter() {
        tm.insert(mk.to_string(), mv.to_string().to_json());
      }
      json::Object(tm)
    }
  }
  
  struct WordDocument&lt;'a&gt; {
    metadata: Vec&lt;(&amp;'a str, &amp;'a str)&gt;
  }
  
  impl&lt;'a&gt; WordDocument&lt;'a&gt; {
    fn new() -&gt; WordDocument&lt;'a&gt; {
      let metadata = vec!(("Title", "Untitled Word Document 1"));
      WordDocument {metadata: metadata}
    }
  }
  
  impl&lt;'a, E, S: Encoder&lt;E&gt;&gt; Encodable&lt;S, E&gt; for WordDocument&lt;'a&gt; {
    fn encode(&amp;self, s: &amp;mut S) -&gt; Result&lt;(), E&gt; {
      s.emit_map(self.metadata.len(), |e| {
        let mut i = 0;
        for &amp;(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(())
      })
    }
  }
  </code></pre>
  
  <p>Rust playpen: <a href="http://is.gd/r7cYmE" rel="noreferrer">http://is.gd/r7cYmE</a></p>
  
  <p>Results:</p>
  
  <pre><code>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"}
  </code></pre>
  
  <p>First method is fully automatic, but does not provide sufficient flexibility.
  Second and third achieve same level of flexibility by specifying the serialization process manually. In my case I want document metadata to be serialized as an object, not as an array (which is what deriving implementation gives me).</p>
  
  <p><strong>Questions</strong>:</p>
  
  <ol>
  <li>Why do methods 2 and 3 exist at all? I don't understand the reason for the overlap between them. I would expect there to exist only one automatic (deriving) method of serialization and one manual. </li>
  <li><p>If I want manual serialization, which method should I choose and why?</p></li>
  <li><p>Am I right in assuming that method 2 will build a <code>Json</code> enum in memory (besides the struct itself) and is a worse fit for huge documents (multi megabytes), while method 3 is streaming and safer for huge documents?</p></li>
  <li><p>Why does rust stdlib use method 3 even for primitives, while not using method 2 internally?</p></li>
  </ol>