Skip to content

Commit

Permalink
Pretty configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Oct 11, 2017
1 parent 1fe3759 commit d8dacf6
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 43 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ron"
version = "0.1.3"
version = "0.1.4"
license = "MIT/Apache-2.0"
keywords = ["parser", "serde", "serialization"]
authors = [
Expand Down
24 changes: 17 additions & 7 deletions examples/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@ extern crate ron;
extern crate serde_derive;

use std::collections::HashMap;
use std::default::Default;
use std::fs::File;

use ron::ser::pretty::to_string;
use ron::ser::{PrettyConfig, to_string_pretty};

#[derive(Serialize)]
struct Config {
boolean: bool,
float: f32,
float: (f32, f64),
tuple: TupleStruct,
map: HashMap<u8, char>,
nested: Nested,
var: Variant,
}

#[derive(Serialize)]
struct TupleStruct((), bool);

#[derive(Serialize)]
enum Variant {
A(u8, &'static str),
Expand All @@ -33,16 +37,22 @@ fn main() {

let mut file = File::create("config.ron").expect("Failed to create file");

let s = to_string(&Config {
boolean: false,
float: 2.18,
let data = Config {
float: (2.18, -1.1),
tuple: TupleStruct((), false),
map: HashMap::from_iter(vec![(0, '1'), (1, '2'), (3, '5'), (8, '1')]),
nested: Nested {
a: "Hello from \"RON\"".to_string(),
b: 'b',
},
var: Variant::A(!0, ""),
}).expect("Serialization failed");
};

let pretty = PrettyConfig {
separate_tuple_members: true,
.. PrettyConfig::default()
};
let s = to_string_pretty(&data, pretty).expect("Serialization failed");

file.write(s.as_bytes()).expect("Failed to write data to file");
}
108 changes: 83 additions & 25 deletions src/ser/mod.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
use std::error::Error as StdError;
use std::result::Result as StdResult;
use std::fmt::{Display, Formatter, Result as FmtResult};

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

#[deprecated]
pub mod pretty;

mod value;

#[cfg(not(target_os = "windows"))]
const NEWLINE: &str = "\n";

#[cfg(target_os = "windows")]
const NEWLINE: &str = "\r\n";

/// Serializes `value` and returns it as string.
///
/// This function does not generate any newlines or nice formatting;
Expand All @@ -29,8 +24,21 @@ pub fn to_string<T>(value: &T) -> Result<String>
Ok(s.output)
}

/// Serializes `value` in the recommended RON layout, make it pretty.
pub fn to_string_pretty<T>(value: &T, config: PrettyConfig) -> Result<String>
where T: Serialize
{
let mut s = Serializer {
output: String::new(),
pretty: Some((config, Pretty { indent: 0 })),
struct_names: false,
};
value.serialize(&mut s)?;
Ok(s.output)
}

/// Serialization result.
pub type Result<T> = ::std::result::Result<T, Error>;
pub type Result<T> = StdResult<T, Error>;

/// Serialization error.
#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -61,38 +69,70 @@ impl StdError for Error {
}
}

/// Pretty serializer state
struct Pretty {
indent: usize,
}

/// Pretty serializer configuration
#[derive(Clone, Debug)]
pub struct PrettyConfig {
/// New line string
pub new_line: String,
/// Indentation string
pub indentor: String,
/// Separate tuple members with indentation
pub separate_tuple_members: bool,
}

impl Default for PrettyConfig {
fn default() -> Self {
PrettyConfig {
#[cfg(not(target_os = "windows"))]
new_line: "\n".to_string(),
#[cfg(target_os = "windows")]
new_line: "\r\n".to_string(),
indentor: " ".to_string(),
separate_tuple_members: false,
}
}
}

/// The RON serializer.
///
/// You can just use `to_string` for deserializing a value.
/// If you want it pretty-printed, take a look at the `pretty` module.
pub struct Serializer {
output: String,
pretty: Option<Pretty>,
pretty: Option<(PrettyConfig, Pretty)>,
struct_names: bool,
}

impl Serializer {
fn separate_tuple_members(&self) -> bool {
match self.pretty {
Some((ref config, _)) => config.separate_tuple_members,
None => false,
}
}

fn start_indent(&mut self) {
if let Some(ref mut pretty) = self.pretty {
if let Some((ref config, ref mut pretty)) = self.pretty {
pretty.indent += 1;
self.output += NEWLINE;
self.output += &config.new_line;
}
}

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

fn end_indent(&mut self) {
if let Some(ref mut pretty) = self.pretty {
if let Some((ref config, ref mut pretty)) = self.pretty {
pretty.indent -= 1;
self.output.extend((0..pretty.indent * 4).map(|_| " "));
self.output.extend((0..pretty.indent).map(|_| config.indentor.as_str()));
}
}
}
Expand Down Expand Up @@ -256,7 +296,9 @@ impl<'a> ser::Serializer for &'a mut Serializer {
{
self.output += variant;
self.output += "(";

value.serialize(&mut *self)?;

self.output += ")";
Ok(())
}
Expand All @@ -272,6 +314,10 @@ impl<'a> ser::Serializer for &'a mut Serializer {
fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
self.output += "(";

if self.separate_tuple_members() {
self.start_indent();
}

Ok(self)
}

Expand All @@ -297,6 +343,10 @@ impl<'a> ser::Serializer for &'a mut Serializer {
self.output += variant;
self.output += "(";

if self.separate_tuple_members() {
self.start_indent();
}

Ok(self)
}

Expand Down Expand Up @@ -351,8 +401,8 @@ impl<'a> ser::SerializeSeq for &'a mut Serializer {
value.serialize(&mut **self)?;
self.output += ",";

if self.pretty.is_some() {
self.output += NEWLINE;
if let Some((ref config, _)) = self.pretty {
self.output += &config.new_line;
}

Ok(())
Expand All @@ -373,20 +423,28 @@ impl<'a> ser::SerializeTuple for &'a mut Serializer {
fn serialize_element<T>(&mut self, value: &T) -> Result<()>
where T: ?Sized + Serialize
{
if self.separate_tuple_members() {
self.indent();
}

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

if self.pretty.is_some() {
self.output += " ";
if let Some((ref config, _)) = self.pretty {
self.output += if self.separate_tuple_members() { &config.new_line } else { " " };
}

Ok(())
}

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

self.output += ")";
Expand Down Expand Up @@ -450,8 +508,8 @@ impl<'a> ser::SerializeMap for &'a mut Serializer {
value.serialize(&mut **self)?;
self.output += ",";

if self.pretty.is_some() {
self.output += NEWLINE;
if let Some((ref config, _)) = self.pretty {
self.output += &config.new_line;
}

Ok(())
Expand Down Expand Up @@ -484,8 +542,8 @@ impl<'a> ser::SerializeStruct for &'a mut Serializer {
value.serialize(&mut **self)?;
self.output += ",";

if self.pretty.is_some() {
self.output += NEWLINE;
if let Some((ref config, _)) = self.pretty {
self.output += &config.new_line;
}

Ok(())
Expand Down
16 changes: 6 additions & 10 deletions src/ser/pretty.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
//! Provides pretty serialization with `to_string`.
//! Provides default pretty serialization with `to_string`.

use super::{Pretty, Result, Serializer};
use super::{Result, to_string_pretty};

use serde::ser::Serialize;
use std::default::Default;

/// Serializes `value` in the recommended RON layout.
/// Serializes `value` in the recommended RON layout with
/// default pretty configuration.
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)
to_string_pretty(value, Default::default())
}

0 comments on commit d8dacf6

Please sign in to comment.