2018-11-16 13:23:29 -06:00
|
|
|
// 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;
|
2019-02-20 19:43:56 -06:00
|
|
|
use std::error::Error;
|
2018-11-16 13:23:29 -06:00
|
|
|
use std::io::Write;
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
|
|
|
use simple_error::SimpleError;
|
|
|
|
use toml;
|
|
|
|
|
2018-12-06 12:23:52 -06:00
|
|
|
use crate::build::Val;
|
2019-02-20 19:43:56 -06:00
|
|
|
use crate::convert::traits::{ConvertResult, Converter, ImportResult, Importer};
|
2018-11-16 13:23:29 -06:00
|
|
|
|
|
|
|
pub struct TomlConverter {}
|
|
|
|
|
2019-02-19 14:50:55 -06:00
|
|
|
type Result = std::result::Result<toml::Value, Box<error::Error>>;
|
2018-11-16 13:23:29 -06:00
|
|
|
|
|
|
|
impl TomlConverter {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
TomlConverter {}
|
|
|
|
}
|
|
|
|
|
2019-02-19 14:50:55 -06:00
|
|
|
fn convert_list(&self, items: &Vec<Rc<Val>>) -> Result {
|
2018-11-16 13:23:29 -06:00
|
|
|
let mut v = Vec::new();
|
|
|
|
for val in items.iter() {
|
2018-12-06 12:46:47 -06:00
|
|
|
v.push(self.convert_value(val)?);
|
2018-11-16 13:23:29 -06:00
|
|
|
}
|
|
|
|
Ok(toml::Value::Array(v))
|
|
|
|
}
|
|
|
|
|
2019-02-19 16:36:19 -06:00
|
|
|
fn convert_tuple(&self, items: &Vec<(String, Rc<Val>)>) -> Result {
|
2018-11-16 13:23:29 -06:00
|
|
|
let mut mp = toml::value::Table::new();
|
|
|
|
for &(ref k, ref v) in items.iter() {
|
2019-02-19 16:36:19 -06:00
|
|
|
mp.entry(k.clone()).or_insert(self.convert_value(v)?);
|
2018-11-16 13:23:29 -06:00
|
|
|
}
|
|
|
|
Ok(toml::Value::Table(mp))
|
|
|
|
}
|
|
|
|
|
2019-02-19 14:50:55 -06:00
|
|
|
fn convert_env(&self, items: &Vec<(String, String)>) -> Result {
|
2018-11-26 21:36:50 -06:00
|
|
|
let mut mp = toml::value::Table::new();
|
|
|
|
for &(ref k, ref v) in items.iter() {
|
|
|
|
mp.entry(k.clone())
|
|
|
|
.or_insert(toml::Value::String(v.clone()));
|
|
|
|
}
|
|
|
|
Ok(toml::Value::Table(mp))
|
|
|
|
}
|
|
|
|
|
2019-02-19 14:50:55 -06:00
|
|
|
fn convert_value(&self, v: &Val) -> Result {
|
2018-11-16 13:23:29 -06:00
|
|
|
let toml_val = match v {
|
|
|
|
&Val::Boolean(b) => toml::Value::Boolean(b),
|
|
|
|
&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()),
|
2019-01-24 20:04:40 -06:00
|
|
|
&Val::Func(_) => {
|
|
|
|
let err = SimpleError::new("Functions are not allowed in Toml Conversions!");
|
2018-11-16 13:23:29 -06:00
|
|
|
return Err(Box::new(err));
|
|
|
|
}
|
2018-11-23 12:50:47 -06:00
|
|
|
&Val::Module(_) => {
|
|
|
|
let err = SimpleError::new("Modules are not allowed in Toml Conversions!");
|
|
|
|
return Err(Box::new(err));
|
|
|
|
}
|
2018-12-06 12:46:47 -06:00
|
|
|
&Val::Env(ref fs) => self.convert_env(fs)?,
|
|
|
|
&Val::List(ref l) => self.convert_list(l)?,
|
|
|
|
&Val::Tuple(ref t) => self.convert_tuple(t)?,
|
2018-11-16 13:23:29 -06:00
|
|
|
};
|
|
|
|
Ok(toml_val)
|
|
|
|
}
|
|
|
|
|
2019-02-20 19:43:56 -06:00
|
|
|
fn convert_toml_val(&self, v: &toml::Value) -> std::result::Result<Val, Box<dyn Error>> {
|
|
|
|
Ok(match v {
|
|
|
|
toml::Value::String(s) => Val::Str(s.clone()),
|
|
|
|
toml::Value::Integer(i) => Val::Int(*i),
|
|
|
|
toml::Value::Float(f) => Val::Float(*f),
|
|
|
|
toml::Value::Boolean(b) => Val::Boolean(*b),
|
|
|
|
toml::Value::Array(l) => {
|
|
|
|
let mut vs = Vec::with_capacity(l.len());
|
|
|
|
for aval in l {
|
|
|
|
vs.push(Rc::new(self.convert_toml_val(aval)?));
|
|
|
|
}
|
|
|
|
Val::List(vs)
|
|
|
|
}
|
|
|
|
toml::Value::Table(m) => {
|
|
|
|
let mut fs = Vec::with_capacity(m.len());
|
|
|
|
for (key, value) in m {
|
|
|
|
fs.push((key.to_string(), Rc::new(self.convert_toml_val(value)?)));
|
|
|
|
}
|
|
|
|
Val::Tuple(fs)
|
|
|
|
}
|
|
|
|
toml::Value::Datetime(d) => Val::Str(format!("{}", d)),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-02-19 14:50:55 -06:00
|
|
|
fn write(&self, v: &Val, w: &mut Write) -> ConvertResult {
|
2018-12-06 12:46:47 -06:00
|
|
|
let toml_val = self.convert_value(v)?;
|
|
|
|
let toml_bytes = toml::ser::to_string_pretty(&toml_val)?;
|
|
|
|
write!(w, "{}", toml_bytes)?;
|
2018-11-16 13:23:29 -06:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Converter for TomlConverter {
|
2019-02-19 14:50:55 -06:00
|
|
|
fn convert(&self, v: Rc<Val>, mut w: &mut Write) -> ConvertResult {
|
2018-11-16 13:23:29 -06:00
|
|
|
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()
|
|
|
|
}
|
2019-03-25 20:23:50 -04:00
|
|
|
|
|
|
|
#[allow(unused_must_use)]
|
|
|
|
fn help(&self) -> String {
|
2019-04-08 22:13:29 -05:00
|
|
|
include_str!("toml_help.txt").to_string()
|
2019-03-25 20:23:50 -04:00
|
|
|
}
|
2018-11-16 13:23:29 -06:00
|
|
|
}
|
2019-02-20 19:43:56 -06:00
|
|
|
|
|
|
|
impl Importer for TomlConverter {
|
|
|
|
fn import(&self, bytes: &[u8]) -> ImportResult {
|
|
|
|
let json_val = toml::from_slice(bytes)?;
|
|
|
|
Ok(Rc::new(self.convert_toml_val(&json_val)?))
|
|
|
|
}
|
|
|
|
}
|