FEATURE: Add toml as an output converter.

closes #4
This commit is contained in:
Jeremy Wall 2018-11-16 13:23:29 -06:00
parent 034aa45458
commit eebe0bbe67
6 changed files with 121 additions and 1 deletions

10
Cargo.lock generated
View File

@ -224,6 +224,14 @@ dependencies = [
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "toml"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "ucg" name = "ucg"
version = "0.2.3" version = "0.2.3"
@ -235,6 +243,7 @@ dependencies = [
"serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "serde_yaml 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"simple-error 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "simple-error 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -316,6 +325,7 @@ dependencies = [
"checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327" "checksum term_size 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum textwrap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8e08afc40ae3459e4838f303e465aa50d823df8d7f83ca88108f6d3afe7edd" "checksum textwrap 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8e08afc40ae3459e4838f303e465aa50d823df8d7f83ca88108f6d3afe7edd"
"checksum toml 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "4a2ecc31b0351ea18b3fe11274b8db6e4d82bce861bbb22e6dbed40417902c65"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"

View File

@ -15,6 +15,7 @@ clap = "~2.26.0"
serde_json = "~1.0.9" serde_json = "~1.0.9"
simple-error = "0.1" simple-error = "0.1"
serde_yaml = "~0.8.1" serde_yaml = "~0.8.1"
toml = "~0.4.8"
[dev-dependencies] [dev-dependencies]
bencher = "~0.1.5" bencher = "~0.1.5"

12
examples/test_toml.ucg Normal file
View File

@ -0,0 +1,12 @@
let config = {
format = "toml",
app = {
name = "app",
version = "v0.0.0",
},
metadata = {
tags = ["foo", "bar"],
},
};
out toml config;

View File

@ -17,6 +17,7 @@ pub mod env;
pub mod exec; pub mod exec;
pub mod flags; pub mod flags;
pub mod json; pub mod json;
pub mod toml;
pub mod traits; pub mod traits;
pub mod yaml; pub mod yaml;
@ -47,6 +48,7 @@ impl ConverterRegistry {
registry.register("flags", Box::new(flags::FlagConverter::new())); registry.register("flags", Box::new(flags::FlagConverter::new()));
registry.register("exec", Box::new(exec::ExecConverter::new())); registry.register("exec", Box::new(exec::ExecConverter::new()));
registry.register("yaml", Box::new(yaml::YamlConverter::new())); registry.register("yaml", Box::new(yaml::YamlConverter::new()));
registry.register("toml", Box::new(toml::TomlConverter::new()));
registry registry
} }

94
src/convert/toml.rs Normal file
View File

@ -0,0 +1,94 @@
// Copyright 2018 Jeremy Wall
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std;
use std::error;
use std::io::Write;
use std::rc::Rc;
use simple_error::SimpleError;
use toml;
use ast;
use build::Val;
use convert::traits::{Converter, Result};
pub struct TomlConverter {}
type ConvertResult = std::result::Result<toml::Value, Box<error::Error>>;
impl TomlConverter {
pub fn new() -> Self {
TomlConverter {}
}
fn convert_list(&self, items: &Vec<Rc<Val>>) -> ConvertResult {
let mut v = Vec::new();
for val in items.iter() {
v.push(try!(self.convert_value(val)));
}
Ok(toml::Value::Array(v))
}
fn convert_tuple(&self, items: &Vec<(ast::PositionedItem<String>, Rc<Val>)>) -> ConvertResult {
let mut mp = toml::value::Table::new();
for &(ref k, ref v) in items.iter() {
mp.entry(k.val.clone())
.or_insert(try!(self.convert_value(v)));
}
Ok(toml::Value::Table(mp))
}
fn convert_value(&self, v: &Val) -> ConvertResult {
let toml_val = match v {
&Val::Boolean(b) => toml::Value::Boolean(b),
// TODO(jwall): This is an error apparently
&Val::Empty => {
let err = SimpleError::new("Nulls are not allowed in Toml Conversions!");
return Err(Box::new(err));
}
&Val::Float(f) => toml::Value::Float(f),
&Val::Int(i) => toml::Value::Integer(i),
&Val::Str(ref s) => toml::Value::String(s.clone()),
&Val::Macro(_) => {
let err = SimpleError::new("Macros are not allowed in Toml Conversions!");
return Err(Box::new(err));
}
&Val::List(ref l) => try!(self.convert_list(l)),
&Val::Tuple(ref t) => try!(self.convert_tuple(t)),
};
Ok(toml_val)
}
fn write(&self, v: &Val, w: &mut Write) -> Result {
let toml_val = try!(self.convert_value(v));
let toml_bytes = try!(toml::ser::to_string_pretty(&toml_val));
try!(write!(w, "{}", toml_bytes));
Ok(())
}
}
impl Converter for TomlConverter {
fn convert(&self, v: Rc<Val>, mut w: &mut Write) -> Result {
self.write(&v, &mut w)
}
fn file_ext(&self) -> String {
String::from("toml")
}
fn description(&self) -> String {
"Convert ucg Vals into valid ucg.".to_string()
}
}

View File

@ -40,7 +40,7 @@
//! //!
//! ## Syntax //! ## Syntax
//! //!
//! A valid ucg file is composesed of a series of statements. Stataments start with an //! A valid ucg file is composed of a series of statements. Statements start with an
//! optional keyword and terminate with a semicolon. //! optional keyword and terminate with a semicolon.
//! //!
//! ### Reserved words //! ### Reserved words
@ -488,6 +488,7 @@ extern crate abortable_parser;
extern crate serde_json; extern crate serde_json;
extern crate serde_yaml; extern crate serde_yaml;
extern crate simple_error; extern crate simple_error;
extern crate toml;
#[macro_use] #[macro_use]
pub mod ast; pub mod ast;