From 3538209002f7e02c409920c5c486b7455150b29e Mon Sep 17 00:00:00 2001 From: Tom Almeida Date: Tue, 17 Mar 2020 13:31:57 +0800 Subject: [PATCH] feat: Make all variables show when running `let`. Before this patch, `let` only shows string and array variables, whilst all mapping types are not shown. In addition, string and array variables are separated from each other by comments. This patch implements a new function on `shell::Variables` that returns all the variables in scope and then modifies `Shell::list_vars` to print all the variables. The syntax returned is equivalent to the method of declaring the variables themselves, however this still results in mapping types being indistinguishable from each other by looking at the output of `let` (both `HashMap` and `BTreeMap` look the same). --- src/lib/shell/assignments.rs | 47 ++++++++++++++++++++++++------------ src/lib/shell/variables.rs | 15 ++++++++++++ 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/lib/shell/assignments.rs b/src/lib/shell/assignments.rs index 2b1ab521..d5ef2c02 100644 --- a/src/lib/shell/assignments.rs +++ b/src/lib/shell/assignments.rs @@ -20,22 +20,39 @@ fn list_vars(shell: &Shell<'_>) -> Result<(), io::Error> { let stdout = io::stdout(); let mut buffer = BufWriter::new(stdout.lock()); - // Write all the string variables to the buffer. - buffer.write_all(b"# String Variables\n")?; - for (key, val) in shell.variables.string_vars() { - writeln!(buffer, "{} = {}", key, val)?; - } - - // Then immediately follow that with a list of array variables. - buffer.write_all(b"\n# Array Variables\n")?; - for (key, val) in shell.variables.arrays() { - write!(buffer, "{} = [ ", key)?; - let mut vars = val.iter(); - if let Some(var) = vars.next() { - write!(buffer, "'{}' ", var)?; - vars.map(|var| write!(buffer, ", '{}' ", var)).collect::, _>>()?; + for (key, val) in shell.variables.variables() { + write!(buffer, "{} = ", key)?; + match val { + Value::Str(ref s) => writeln!(buffer, "{}", s)?, + Value::Array(ref vals) => { + write!(buffer, "[")?; + let mut vals = vals.iter(); + if let Some(val) = vals.next() { + write!(buffer, " '{}'", val)?; + vals.map(|v| write!(buffer, ", '{}'", v)).collect::, _>>()?; + } + writeln!(buffer, " ]")?; + }, + Value::HashMap(ref s) => { + write!(buffer, "[")?; + let mut vals = s.iter(); + if let Some((key, val)) = vals.next() { + write!(buffer, " '{}'='{}'", key, val)?; + vals.map(|(k, v)| write!(buffer, ", '{}'='{}'", k, v)).collect::, _>>()?; + } + writeln!(buffer, " ]")?; + }, + Value::BTreeMap(ref s) => { + write!(buffer, "[")?; + let mut vals = s.iter(); + if let Some((key, val)) = vals.next() { + write!(buffer, " '{}'='{}'", key, val)?; + vals.map(|(k, v)| write!(buffer, ", '{}'='{}'", k, v)).collect::, _>>()?; + } + writeln!(buffer, " ]")?; + }, + _ => unsafe { std::hint::unreachable_unchecked() } } - writeln!(buffer, "]")?; } Ok(()) } diff --git a/src/lib/shell/variables.rs b/src/lib/shell/variables.rs index b4ee1d64..d68d2f52 100644 --- a/src/lib/shell/variables.rs +++ b/src/lib/shell/variables.rs @@ -54,6 +54,21 @@ impl<'a> Variables<'a> { }) } + /// Get all the variables + pub fn variables(&self) -> impl Iterator>>)> { + self.0.scopes().rev().flat_map(|map| { + map.iter().filter_map(|(key, val)| { + match val { + val @ Value::Array(_) | + val @ Value::Str(_) | + val @ Value::HashMap(_) | + val @ Value::BTreeMap(_) => Some((key, val)), + _ => None + } + }) + }) + } + /// Get all the array values pub fn arrays(&self) -> impl Iterator>>)> { self.0.scopes().rev().flat_map(|map| { -- GitLab