From 5a6737d858ef4beb2f587544bd3bfcb6c76f3bb0 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Mon, 12 Feb 2018 22:47:42 -0600 Subject: [PATCH] Add an environment variable output target. --- examples/env.txt | 1 + src/convert/env.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++ src/convert/flags.rs | 2 +- src/convert/mod.rs | 16 +++++++-- 4 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 examples/env.txt create mode 100644 src/convert/env.rs diff --git a/examples/env.txt b/examples/env.txt new file mode 100644 index 0000000..bea1788 --- /dev/null +++ b/examples/env.txt @@ -0,0 +1 @@ +dbconn_list=db_conn1='db1.prod.net:3306/testdb' db_conn2='db2.prod.net:3306/testdb' tmpldir='./templates' \ No newline at end of file diff --git a/src/convert/env.rs b/src/convert/env.rs new file mode 100644 index 0000000..b4bf24d --- /dev/null +++ b/src/convert/env.rs @@ -0,0 +1,86 @@ +// Copyright 2017 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. + +//! An environment variable converter. +use std::rc::Rc; +use std::io::Write; +use std::io::Result; + +use ast; +use build::Val; +use convert::traits::Converter; + +/// EnvConverter implements the conversion logic for converting a Val into a set of environment variables. +pub struct EnvConverter {} + +impl EnvConverter { + pub fn new() -> Self { + EnvConverter {} + } + + fn convert_tuple( + &self, + flds: &Vec<(ast::Positioned, Rc)>, + w: &mut Write, + ) -> Result<()> { + for &(ref name, ref val) in flds.iter() { + // TODO(jwall): What if the value is a tuple? + if val.is_tuple() { + eprintln!("Skipping embedded tuple..."); + return Ok(()); + } + try!(write!(w, "{}=", name.val)); + try!(self.write(&val, w)); + } + Ok(()) + } + + fn convert_list(&self, _items: &Vec>, _w: &mut Write) -> Result<()> { + // FIXME(jwall): Fill this in? + // TODO(jwall) + eprintln!("Skipping List..."); + Ok(()) + } + + fn write(&self, v: &Val, w: &mut Write) -> Result<()> { + match v { + &Val::Float(ref f) => { + try!(write!(w, "{} ", f)); + } + &Val::Int(ref i) => { + try!(write!(w, "{} ", i)); + } + &Val::String(ref s) => { + try!(write!(w, "'{}' ", s)); + } + &Val::List(ref items) => { + try!(self.convert_list(items, w)); + } + &Val::Tuple(ref flds) => { + try!(self.convert_tuple(flds, w)); + } + &Val::Macro(ref _def) => { + // This is ignored + eprintln!("Skipping macro..."); + } + } + Ok(()) + } +} + +impl Converter for EnvConverter { + fn convert(&self, v: Rc, mut w: Box) -> Result<()> { + self.write(&v, &mut w) + } +} diff --git a/src/convert/flags.rs b/src/convert/flags.rs index d384609..d628a00 100644 --- a/src/convert/flags.rs +++ b/src/convert/flags.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Flags contains code for converting a UCG Val into the command line flag output target. +//! Contains code for converting a UCG Val into the command line flag output target. use std::rc::Rc; use std::io::Write; use std::io::Result; diff --git a/src/convert/mod.rs b/src/convert/mod.rs index e06d8a4..3c32071 100644 --- a/src/convert/mod.rs +++ b/src/convert/mod.rs @@ -15,6 +15,7 @@ //! The conversion stage of the ucg compiler. pub mod flags; pub mod json; +pub mod env; pub mod traits; use std::io; @@ -30,15 +31,24 @@ pub struct ConverterRunner { impl ConverterRunner { /// new creates a new ConverterRunner with a converter for the provided output target. - /// + /// /// * flags /// * json pub fn new(typ: &str) -> Result { if typ == "flags" { - return Ok(ConverterRunner { converter: Box::new(flags::FlagConverter::new()) }); + return Ok(ConverterRunner { + converter: Box::new(flags::FlagConverter::new()), + }); } if typ == "json" { - return Ok(ConverterRunner { converter: Box::new(json::JsonConverter::new()) }); + return Ok(ConverterRunner { + converter: Box::new(json::JsonConverter::new()), + }); + } + if typ == "env" { + return Ok(ConverterRunner { + converter: Box::new(env::EnvConverter::new()), + }); } return Err(format!("Unknown Target output type: {}", typ)); }