From 07413c9e8d328a5b824ae6dc7d55f9c9d99e3577 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Thu, 15 Mar 2018 19:31:02 -0500 Subject: [PATCH] Add list flag support. If a field has a list of primitive values in it expand it to multiples of that flag for each value in the list. --- examples/test.ucg | 3 ++- src/build.rs | 16 +++++++++++++- src/convert/flags.rs | 50 +++++++++++++++++++++++++++++++------------- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/examples/test.ucg b/examples/test.ucg index 79f8933..be93338 100644 --- a/examples/test.ucg +++ b/examples/test.ucg @@ -24,5 +24,6 @@ let server_config = { tmpldir = "./templates", prefix = { foo = "bar" - } + }, + l = ["foo", "bar"] }; \ No newline at end of file diff --git a/src/build.rs b/src/build.rs index f64ed90..9b98231 100644 --- a/src/build.rs +++ b/src/build.rs @@ -126,6 +126,13 @@ impl Val { return false; } + pub fn is_empty(&self) -> bool { + if let &Val::Empty = self { + return true; + } + return false; + } + pub fn is_float(&self) -> bool { if let &Val::Float(_) = self { return true; @@ -148,7 +155,14 @@ impl Val { } pub fn is_list(&self) -> bool { - if let &Val::Tuple(_) = self { + if let &Val::List(_) = self { + return true; + } + return false; + } + + pub fn is_macro(&self) -> bool { + if let &Val::Macro(_) = self { return true; } return false; diff --git a/src/convert/flags.rs b/src/convert/flags.rs index aea753b..1c048f2 100644 --- a/src/convert/flags.rs +++ b/src/convert/flags.rs @@ -37,6 +37,27 @@ impl FlagConverter { return Ok(()); } + fn write_list_flag(&self, pfx: &str, name: &str, v: &Val, w: &mut Write) -> Result<()> { + if let &Val::List(ref def) = v { + // first of all we need to make sure that each &Val is only a primitive type. + for v in def.iter() { + let vref = v.as_ref(); + if vref.is_list() || vref.is_tuple() || vref.is_macro() { + eprintln!( + "Skipping non primitive val in list for flag {}{}", + pfx, name + ); + } else { + try!(self.write_flag_name(pfx, name, w)); + try!(self.write(pfx, vref, w)); + } + } + } else { + panic!("Impossible call happened. Somebody messed up.") + } + return Ok(()); + } + fn write(&self, pfx: &str, v: &Val, w: &mut Write) -> Result<()> { match v { &Val::Empty => { @@ -56,22 +77,21 @@ impl FlagConverter { // FIXME(jwall): Fill this in? eprintln!("Skipping List..."); } - &Val::Tuple(ref flds) => { - for &(ref name, ref val) in flds.iter() { - if let &Val::Empty = val.as_ref() { - try!(self.write_flag_name(pfx, &name.val, w)); - continue; - } - if val.is_tuple() { - let new_pfx = format!("{}{}.", pfx, name); - try!(self.write(&new_pfx, val, w)); - } else { - try!(self.write_flag_name(pfx, &name.val, w)); - // TODO(jwall): What if the value is a tuple? - try!(self.write(pfx, &val, w)); - } + &Val::Tuple(ref flds) => for &(ref name, ref val) in flds.iter() { + if let &Val::Empty = val.as_ref() { + try!(self.write_flag_name(pfx, &name.val, w)); + continue; } - } + if val.is_tuple() { + let new_pfx = format!("{}{}.", pfx, name); + try!(self.write(&new_pfx, val, w)); + } else if val.is_list() { + try!(self.write_list_flag(pfx, &name.val, &val, w)); + } else { + try!(self.write_flag_name(pfx, &name.val, w)); + try!(self.write(pfx, &val, w)); + } + }, &Val::Macro(ref _def) => { // This is ignored eprintln!("Skipping macro...");