Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pretty option to serializer #25

Merged
merged 2 commits into from
Jul 31, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extern crate serde_derive;
use std::collections::HashMap;
use std::fs::File;

use ron::ser::to_string;
use ron::ser::pretty::to_string;

#[derive(Serialize)]
struct Config {
Expand Down
126 changes: 100 additions & 26 deletions src/ser.rs → src/ser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ use std::fmt::{Display, Formatter, Result as FmtResult};

use serde::ser::{self, Serialize};

pub mod pretty;

/// Serializes `value` and returns it as string.
pub fn to_string<T>(value: &T) -> Result<String>
where T: Serialize
{
let mut s = Serializer {
output: String::new(),
pretty: None,
struct_names: false,
};
value.serialize(&mut s)?;
Expand Down Expand Up @@ -46,11 +49,38 @@ impl StdError for Error {
}
}

struct Pretty {
indent: usize,
}

pub struct Serializer {
output: String,
pretty: Option<Pretty>,
struct_names: bool,
}

impl Serializer {
fn start_indent(&mut self) {
if let Some(ref mut pretty) = self.pretty {
pretty.indent += 1;
self.output += "\n";
}
}

fn indent(&mut self) {
if let Some(ref pretty) = self.pretty {
self.output.extend((0..pretty.indent * 4).map(|_| " "));
}
}

fn end_indent(&mut self) {
if let Some(ref mut pretty) = self.pretty {
pretty.indent -= 1;
self.output.extend((0..pretty.indent * 4).map(|_| " "));
}
}
}

impl<'a> ser::Serializer for &'a mut Serializer {
type Ok = ();
type Error = Error;
Expand Down Expand Up @@ -166,9 +196,13 @@ impl<'a> ser::Serializer for &'a mut Serializer {
}

fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
self.output += name;
if self.struct_names {
self.output += name;

Ok(())
Ok(())
} else {
self.serialize_unit()
}
}

fn serialize_unit_variant(
Expand Down Expand Up @@ -207,13 +241,15 @@ impl<'a> ser::Serializer for &'a mut Serializer {
self.output += variant;
self.output += "(";
value.serialize(&mut *self)?;
self.output += ",)";
self.output += ")";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes the compilation issue. Any idea why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind, found the issue.

Ok(())
}

fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
self.output += "[";

self.start_indent();

Ok(self)
}

Expand Down Expand Up @@ -245,12 +281,16 @@ impl<'a> ser::Serializer for &'a mut Serializer {
self.output += variant;
self.output += "(";

self.start_indent();

Ok(self)
}

fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
self.output += "{";

self.start_indent();

Ok(self)
}

Expand All @@ -264,6 +304,8 @@ impl<'a> ser::Serializer for &'a mut Serializer {
}
self.output += "(";

self.start_indent();

Ok(self)
}

Expand All @@ -276,6 +318,9 @@ impl<'a> ser::Serializer for &'a mut Serializer {
) -> Result<Self::SerializeStructVariant> {
self.output += variant;
self.output += "(";

self.start_indent();

Ok(self)
}
}
Expand All @@ -287,12 +332,21 @@ impl<'a> ser::SerializeSeq for &'a mut Serializer {
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + Serialize
{
self.indent();

value.serialize(&mut **self)?;
self.output += ",";

if self.pretty.is_some() {
self.output += "\n";
}

Ok(())
}

fn end(self) -> Result<()> {
self.end_indent();

self.output += "]";
Ok(())
}
Expand All @@ -308,10 +362,19 @@ impl<'a> ser::SerializeTuple for &'a mut Serializer {
value.serialize(&mut **self)?;
self.output += ",";

if self.pretty.is_some() {
self.output += " ";
}

Ok(())
}

fn end(self) -> Result<()> {
if self.pretty.is_some() {
self.output.pop();
self.output.pop();
}

self.output += ")";

Ok(())
Expand All @@ -326,16 +389,11 @@ impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + Serialize
{
value.serialize(&mut **self)?;
self.output += ",";

Ok(())
ser::SerializeTuple::serialize_element(self, value)
}

fn end(self) -> Result<()> {
self.output += ")";

Ok(())
ser::SerializeTuple::end(self)
}
}

Expand All @@ -346,15 +404,11 @@ impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
fn serialize_field<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + Serialize
{
value.serialize(&mut **self)?;
self.output += ",";

Ok(())
ser::SerializeTuple::serialize_element(self, value)
}

fn end(self) -> Result<()> {
self.output += ")";
Ok(())
ser::SerializeTuple::end(self)
}
}

Expand All @@ -365,20 +419,33 @@ impl<'a> ser::SerializeMap for &'a mut Serializer {
fn serialize_key<T>(&mut self, key: &T) -> Result<()>
where T: ?Sized + Serialize
{
self.indent();

key.serialize(&mut **self)
}

fn serialize_value<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + Serialize
{
self.output += ":";

if self.pretty.is_some() {
self.output += " ";
}

value.serialize(&mut **self)?;
self.output += ",";

if self.pretty.is_some() {
self.output += "\n";
}

Ok(())
}

fn end(self) -> Result<()> {
self.end_indent();

self.output += "}";
Ok(())
}
Expand All @@ -391,15 +458,28 @@ impl<'a> ser::SerializeStruct for &'a mut Serializer {
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where T: ?Sized + Serialize
{
self.indent();

self.output += key;
self.output += ":";

if self.pretty.is_some() {
self.output += " ";
}

value.serialize(&mut **self)?;
self.output += ",";

if self.pretty.is_some() {
self.output += "\n";
}

Ok(())
}

fn end(self) -> Result<()> {
self.end_indent();

self.output += ")";
Ok(())
}
Expand All @@ -412,17 +492,11 @@ impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
where T: ?Sized + Serialize
{
self.output += key;
self.output += ":";
value.serialize(&mut **self)?;
self.output += ",";

Ok(())
ser::SerializeStruct::serialize_field(self, key, value)
}

fn end(self) -> Result<()> {
self.output += ")";
Ok(())
ser::SerializeStruct::end(self)
}
}

Expand All @@ -449,7 +523,7 @@ mod tests {

#[test]
fn test_empty_struct() {
assert_eq!(to_string(&EmptyStruct1).unwrap(), "EmptyStruct1");
assert_eq!(to_string(&EmptyStruct1).unwrap(), "()");
assert_eq!(to_string(&EmptyStruct2 {}).unwrap(), "()");
}

Expand Down Expand Up @@ -480,7 +554,7 @@ mod tests {
#[test]
fn test_enum() {
assert_eq!(to_string(&MyEnum::A).unwrap(), "A");
assert_eq!(to_string(&MyEnum::B(true)).unwrap(), "B(true,)");
assert_eq!(to_string(&MyEnum::B(true)).unwrap(), "B(true)");
assert_eq!(to_string(&MyEnum::C(true, 3.5)).unwrap(), "C(true,3.5,)");
assert_eq!(to_string(&MyEnum::D { a: 2, b: 3 }).unwrap(), "D(a:2,b:3,)");
}
Expand Down
15 changes: 15 additions & 0 deletions src/ser/pretty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use super::{Pretty, Result, Serializer};

use serde::ser::Serialize;

pub fn to_string<T>(value: &T) -> Result<String>
where T: Serialize
{
let mut s = Serializer {
output: String::new(),
pretty: Some(Pretty { indent: 0 }),
struct_names: false,
};
value.serialize(&mut s)?;
Ok(s.output)
}
3 changes: 3 additions & 0 deletions tests/roundtrip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ fn roundtrip() {
};

let serial = ron::ser::to_string(&value).unwrap();

println!("Serialized: {}", serial);

let deserial = ron::de::from_str(&serial);

assert_eq!(Ok(value), deserial);
Expand Down