Commit 35382090 authored by Tom Almeida's avatar Tom Almeida Committed by AdminXVII
Browse files

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).
parent 42e40e90
......@@ -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::<Result<Vec<_>, _>>()?;
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::<Result<Vec<_>, _>>()?;
}
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::<Result<Vec<_>, _>>()?;
}
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::<Result<Vec<_>, _>>()?;
}
writeln!(buffer, " ]")?;
},
_ => unsafe { std::hint::unreachable_unchecked() }
}
writeln!(buffer, "]")?;
}
Ok(())
}
......
......@@ -54,6 +54,21 @@ impl<'a> Variables<'a> {
})
}
/// Get all the variables
pub fn variables(&self) -> impl Iterator<Item = (&types::Str, &Value<Rc<Function<'a>>>)> {
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<Item = (&types::Str, &types::Array<Rc<Function<'a>>>)> {
self.0.scopes().rev().flat_map(|map| {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment