Repository: ron-rs/ron
Pull request #87 (2018-01-24 18:35:04)

[v0.1] Implement sequence indexing
Brother of #86 for our released branch.


Patch:
diff --git a/examples/encode.rs b/examples/encode.rs
index bae7b20c..a514961a 100644
--- a/examples/encode.rs
+++ b/examples/encode.rs
@@ -15,6 +15,7 @@ struct Config {
     map: HashMap<u8, char>,
     nested: Nested,
     var: Variant,
+    array: Vec<()>,
 }
 
 #[derive(Serialize)]
@@ -46,6 +47,7 @@ fn main() {
             b: 'b',
         },
         var: Variant::A(!0, ""),
+        array: vec![(); 3],
     };
 
     let pretty = PrettyConfig {
diff --git a/src/ser/mod.rs b/src/ser/mod.rs
index 22e83bd5..929beac0 100644
--- a/src/ser/mod.rs
+++ b/src/ser/mod.rs
@@ -1,6 +1,6 @@
 use std::error::Error as StdError;
+use std::fmt::{Display, Formatter, Write, Result as FmtResult};
 use std::result::Result as StdResult;
-use std::fmt::{Display, Formatter, Result as FmtResult};
 
 use serde::ser::{self, Serialize};
 
@@ -30,7 +30,7 @@ pub fn to_string_pretty<T>(value: &T, config: PrettyConfig) -> Result<String>
 {
     let mut s = Serializer {
         output: String::new(),
-        pretty: Some((config, Pretty { indent: 0 })),
+        pretty: Some((config, Pretty { indent: 0, sequence_index: 0 })),
         struct_names: false,
     };
     value.serialize(&mut s)?;
@@ -72,6 +72,7 @@ impl StdError for Error {
 /// Pretty serializer state
 struct Pretty {
     indent: usize,
+    sequence_index: usize,
 }
 
 /// Pretty serializer configuration
@@ -83,6 +84,8 @@ pub struct PrettyConfig {
     pub indentor: String,
     /// Separate tuple members with indentation
     pub separate_tuple_members: bool,
+    /// Enumerate array items in comments
+    pub enumerate_arrays: bool,
 }
 
 impl Default for PrettyConfig {
@@ -94,6 +97,7 @@ impl Default for PrettyConfig {
             new_line: "\r\n".to_string(),
             indentor: "    ".to_string(),
             separate_tuple_members: false,
+            enumerate_arrays: false,
         }
     }
 }
@@ -115,7 +119,7 @@ impl Serializer {
     pub fn new(config: Option<PrettyConfig>, struct_names: bool) -> Self {
         Serializer {
             output: String::new(),
-            pretty: config.map(|conf| (conf, Pretty { indent: 0 })),
+            pretty: config.map(|conf| (conf, Pretty { indent: 0, sequence_index: 0 })),
             struct_names,
         }
     }
@@ -237,6 +241,7 @@ impl<'a> ser::Serializer for &'a mut Serializer {
 
     fn serialize_bytes(self, v: &[u8]) -> Result<()> {
         use serde::ser::SerializeSeq;
+        //TODO: shorter version? e.g. base64 encoding in a single line
         let mut seq = self.serialize_seq(Some(v.len()))?;
         for byte in v {
             seq.serialize_element(byte)?;
@@ -323,6 +328,10 @@ impl<'a> ser::Serializer for &'a mut Serializer {
 
         self.start_indent();
 
+        if let Some((_, ref mut pretty)) = self.pretty {
+            pretty.sequence_index = 0;
+        }
+
         Ok(self)
     }
 
@@ -416,8 +425,16 @@ impl<'a> ser::SerializeSeq for &'a mut Serializer {
         value.serialize(&mut **self)?;
         self.output += ",";
 
-        if let Some((ref config, _)) = self.pretty {
+        if let Some((ref config, ref mut pretty)) = self.pretty {
+            if config.enumerate_arrays {
+                assert!(config.new_line.contains('\n'));
+                //TODO: when /**/ comments are supported, prepend the index
+                // to an element instead of appending it.
+                // Note: this doesn't if `new_line` is not an actual new line.
+                write!(self.output, "// [{}]", pretty.sequence_index).unwrap();
+            }
             self.output += &config.new_line;
+            pretty.sequence_index += 1;
         }
 
         Ok(())


Test patch:
diff --git a/tests/roundtrip.rs b/tests/roundtrip.rs
index c88b9f48..b1d8ea19 100644
--- a/tests/roundtrip.rs
+++ b/tests/roundtrip.rs
@@ -51,3 +51,30 @@ fn roundtrip() {
 
     assert_eq!(Ok(value), deserial);
 }
+
+#[test]
+fn roundtrip_pretty() {
+    let value = Struct {
+        tuple: ((), NewType(0.5), TupleStruct(UnitStruct, -5)),
+        vec: vec![None, Some(UnitStruct)],
+        map: vec![
+            (Key(5), Enum::Unit),
+            (Key(6), Enum::Bool(false)),
+            (Key(7), Enum::Bool(true)),
+            (Key(9), Enum::Chars('x', "".to_string())),
+        ].into_iter()
+            .collect(),
+    };
+
+    let pretty = ron::ser::PrettyConfig {
+        enumerate_arrays: true,
+        .. Default::default()
+    };
+    let serial = ron::ser::to_string_pretty(&value, pretty).unwrap();
+
+    println!("Serialized: {}", serial);
+
+    let deserial = ron::de::from_str(&serial);
+
+    assert_eq!(Ok(value), deserial);
+}