Repository: ron-rs/ron (Rust)

Issue:
Don't split empty sets/arrays into multiple lines
I noticed a lot of sections like this:
```ron
                            vertical_blurs: [
                            ],
                            horizontal_blurs: [
                            ],
                            scalings: [
                            ],
                            blits: [
                            ],
                            outputs: [
                            ],
```

I think it would be strictly an improvement if we detect that a set/map/array is empty and avoid inserting a new line in this case.


Discussion:

Patch:
diff --git a/src/ser/mod.rs b/src/ser/mod.rs
index 855c5e8db..7e62a3541 100644
--- a/src/ser/mod.rs
+++ b/src/ser/mod.rs
@@ -18,6 +18,7 @@ where
         output: String::new(),
         pretty: None,
         struct_names: false,
+        is_empty: None,
     };
     value.serialize(&mut s)?;
     Ok(s.output)
@@ -38,6 +39,7 @@ where
             },
         )),
         struct_names: false,
+        is_empty: None,
     };
     value.serialize(&mut s)?;
     Ok(s.output)
@@ -119,6 +121,7 @@ pub struct Serializer {
     output: String,
     pretty: Option<(PrettyConfig, Pretty)>,
     struct_names: bool,
+    is_empty: Option<bool>,
 }
 
 impl Serializer {
@@ -138,6 +141,7 @@ impl Serializer {
                 )
             }),
             struct_names,
+            is_empty: None,
         }
     }
 
@@ -163,7 +167,11 @@ impl Serializer {
         if let Some((ref config, ref mut pretty)) = self.pretty {
             pretty.indent += 1;
             if pretty.indent < config.depth_limit {
-                self.output += &config.new_line;
+                let is_empty = self.is_empty.unwrap_or(false);
+
+                if !is_empty {
+                    self.output += &config.new_line;
+                }
             }
         }
     }
@@ -180,10 +188,16 @@ impl Serializer {
     fn end_indent(&mut self) {
         if let Some((ref config, ref mut pretty)) = self.pretty {
             if pretty.indent < config.depth_limit {
-                self.output
-                    .extend((1..pretty.indent).map(|_| config.indentor.as_str()));
+                let is_empty = self.is_empty.unwrap_or(false);
+
+                if !is_empty {
+                    self.output
+                        .extend((1..pretty.indent).map(|_| config.indentor.as_str()));
+                }
             }
             pretty.indent -= 1;
+
+            self.is_empty = None;
         }
     }
 
@@ -349,9 +363,13 @@ impl<'a> ser::Serializer for &'a mut Serializer {
         Ok(())
     }
 
-    fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
+    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
         self.output += "[";
 
+        if let Some(len) = len {
+            self.is_empty = Some(len == 0);
+        }
+
         self.start_indent();
 
         if let Some((_, ref mut pretty)) = self.pretty {
@@ -361,10 +379,12 @@ impl<'a> ser::Serializer for &'a mut Serializer {
         Ok(self)
     }
 
-    fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
+    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
         self.output += "(";
 
         if self.separate_tuple_members() {
+            self.is_empty = Some(len == 0);
+
             self.start_indent();
         }
 
@@ -388,32 +408,39 @@ impl<'a> ser::Serializer for &'a mut Serializer {
         _: &'static str,
         _: u32,
         variant: &'static str,
-        _: usize,
+        len: usize,
     ) -> Result<Self::SerializeTupleVariant> {
         self.output += variant;
         self.output += "(";
 
         if self.separate_tuple_members() {
+            self.is_empty = Some(len == 0);
+
             self.start_indent();
         }
 
         Ok(self)
     }
 
-    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
         self.output += "{";
 
+        if let Some(len) = len {
+            self.is_empty = Some(len == 0);
+        }
+
         self.start_indent();
 
         Ok(self)
     }
 
-    fn serialize_struct(self, name: &'static str, _: usize) -> Result<Self::SerializeStruct> {
+    fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
         if self.struct_names {
             self.output += name;
         }
         self.output += "(";
 
+        self.is_empty = Some(len == 0);
         self.start_indent();
 
         Ok(self)
@@ -424,11 +451,12 @@ impl<'a> ser::Serializer for &'a mut Serializer {
         _: &'static str,
         _: u32,
         variant: &'static str,
-        _: usize,
+        len: usize,
     ) -> Result<Self::SerializeStructVariant> {
         self.output += variant;
         self.output += "(";
 
+        self.is_empty = Some(len == 0);
         self.start_indent();
 
         Ok(self)


Test patch:
diff --git a/tests/147_empty_sets_serialisation.rs b/tests/147_empty_sets_serialisation.rs
new file mode 100644
index 000000000..0fdb3e2b0
--- /dev/null
+++ b/tests/147_empty_sets_serialisation.rs
@@ -0,0 +1,73 @@
+use serde::{Deserialize, Serialize};
+use std::collections::HashMap;
+
+#[derive(Debug, PartialEq, Deserialize, Serialize)]
+struct UnitStruct;
+
+#[derive(Debug, PartialEq, Deserialize, Serialize)]
+struct NewType(f32);
+
+#[derive(Debug, PartialEq, Deserialize, Serialize)]
+struct TupleStruct(UnitStruct, i8);
+
+#[derive(Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
+struct Key(u32);
+
+#[derive(Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
+enum Enum {
+    Unit,
+    Bool(bool),
+    Chars(char, String),
+}
+
+#[derive(Debug, PartialEq, Deserialize, Serialize)]
+struct Struct {
+    tuple: ((), NewType, TupleStruct),
+    vec: Vec<Option<UnitStruct>>,
+    map: HashMap<Key, Enum>,
+    deep_vec: HashMap<Key, Vec<()>>,
+    deep_map: HashMap<Key, HashMap<Key, Enum>>,
+}
+
+#[test]
+fn empty_sets_arrays() {
+    let value = Struct {
+        tuple: ((), NewType(0.5), TupleStruct(UnitStruct, -5)),
+        vec: vec![],
+        map: vec![]
+        .into_iter()
+        .collect(),
+        deep_vec: vec![
+            (Key(0), vec![]),
+        ]
+        .into_iter()
+        .collect(),
+        deep_map: vec![
+            (Key(0), vec![].into_iter().collect(),),
+        ].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);
+
+    assert_eq!("(
+    tuple: ((), (0.5), ((), -5)),
+    vec: [],
+    map: {},
+    deep_vec: {
+        (0): [],
+    },
+    deep_map: {
+        (0): {},
+    },
+)", serial);
+
+    let deserial = ron::de::from_str(&serial);
+
+    assert_eq!(Ok(value), deserial);
+}