diff --git a/src/lib/builtins/exists.rs b/src/lib/builtins/exists.rs index 0844ada3ffb8165c6e4c7d3f52f7d834b04adc1f..95a733ac619a445193eb47eefd14b38944e2ff15 100644 --- a/src/lib/builtins/exists.rs +++ b/src/lib/builtins/exists.rs @@ -5,7 +5,6 @@ use std::{fs, os::unix::fs::PermissionsExt}; #[cfg(test)] use shell::{ self, - variables::VariableType, flow_control::Statement, }; use shell::{ @@ -172,11 +171,11 @@ fn test_evaluate_arguments() { assert_eq!(evaluate_arguments(&["-a".to_owned()], &shell), Ok(true)); shell .variables - .set_variable("emptyarray", VariableType::Array(Vec::new().into())); + .set("emptyarray", types::Array::new()); assert_eq!(evaluate_arguments(&["-a".to_owned(), "emptyarray".to_owned()], &shell), Ok(false)); - let mut vec = Vec::new(); - vec.push("element".to_owned()); - shell.variables.set_variable("array", VariableType::Array(vec.into())); + let mut array = types::Array::new(); + array.push("element".to_owned()); + shell.variables.set("array", array); assert_eq!(evaluate_arguments(&["-a".to_owned(), "array".to_owned()], &shell), Ok(true)); shell.variables.remove_variable("array"); assert_eq!(evaluate_arguments(&["-a".to_owned(), "array".to_owned()], &shell), Ok(false)); @@ -186,7 +185,7 @@ fn test_evaluate_arguments() { // no argument means we treat it as a string assert_eq!(evaluate_arguments(&["-b".to_owned()], &shell), Ok(true)); let oldpath = shell.get::<types::Value>("PATH").unwrap_or("/usr/bin".to_owned()); - shell.set_variable("PATH", VariableType::Str("testing/".into())); + shell.set("PATH", "testing/".to_string()); assert_eq!( evaluate_arguments(&["-b".to_owned(), "executable_file".to_owned()], &shell), @@ -200,7 +199,7 @@ fn test_evaluate_arguments() { // restore original PATH. Not necessary for the currently defined test cases // but this might change in the future? Better safe than sorry! - shell.set_variable("PATH", VariableType::Str(oldpath)); + shell.set("PATH", oldpath); // check `exists -d` // no argument means we treat it as a string @@ -231,17 +230,17 @@ fn test_evaluate_arguments() { // check `exists -s` // no argument means we treat it as a string assert_eq!(evaluate_arguments(&["-s".to_owned()], &shell), Ok(true)); - shell.set_variable("emptyvar", VariableType::Str("".into())); + shell.set("emptyvar", "".to_string()); assert_eq!(evaluate_arguments(&["-s".to_owned(), "emptyvar".to_owned()], &shell), Ok(false)); - shell.set_variable("testvar", VariableType::Str("foobar".into())); + shell.set("testvar", "foobar".to_string()); assert_eq!(evaluate_arguments(&["-s".to_owned(), "testvar".to_owned()], &shell), Ok(true)); shell.variables.remove_variable("testvar"); assert_eq!(evaluate_arguments(&["-s".to_owned(), "testvar".to_owned()], &shell), Ok(false)); // also check that it doesn't trigger on arrays - let mut vec = Vec::new(); - vec.push("element".to_owned()); + let mut array = types::Array::new(); + array.push("element".to_owned()); shell.variables.remove_variable("array"); - shell.variables.set_variable("array", VariableType::Array(vec.into())); + shell.variables.set("array", array); assert_eq!(evaluate_arguments(&["-s".to_owned(), "array".to_owned()], &shell), Ok(false)); // check `exists --fn` @@ -256,9 +255,9 @@ fn test_evaluate_arguments() { statements.push(Statement::End); let description = "description".to_owned(); - shell.variables.set_variable( + shell.variables.set( &name, - VariableType::Function(Function::new(Some(description), name.clone(), args, statements)), + Function::new(Some(description), name.clone(), args, statements), ); assert_eq!(evaluate_arguments(&["--fn".to_owned(), name_str.to_owned()], &shell), Ok(true)); @@ -339,7 +338,7 @@ fn test_binary_is_in_path() { // TODO: PATH containing directories without read permission (for user) // TODO: PATH containing directories without execute ("enter") permission (for // user) TODO: empty PATH? - shell.set_variable("PATH", VariableType::Str("testing/".into())); + shell.set("PATH", "testing/".to_string()); assert_eq!(binary_is_in_path("executable_file", &shell), true); assert_eq!(binary_is_in_path("empty_file", &shell), false); @@ -364,12 +363,12 @@ fn test_string_is_nonzero() { fn test_array_var_is_not_empty() { let mut shell = shell::ShellBuilder::new().as_library(); - shell.variables.set_variable("EMPTY_ARRAY", VariableType::Array(Vec::new().into())); + shell.variables.set("EMPTY_ARRAY", types::Array::new()); assert_eq!(array_var_is_not_empty("EMPTY_ARRAY", &shell), false); - let mut not_empty_vec = Vec::new(); - not_empty_vec.push("array not empty".to_owned()); - shell.variables.set_variable("NOT_EMPTY_ARRAY", VariableType::Array(not_empty_vec.into())); + let mut not_empty_array = types::Array::new(); + not_empty_array.push("array not empty".to_owned()); + shell.variables.set("NOT_EMPTY_ARRAY", not_empty_array); assert_eq!(array_var_is_not_empty("NOT_EMPTY_ARRAY", &shell), true); // test for array which does not even exist @@ -378,7 +377,7 @@ fn test_array_var_is_not_empty() { // array_var_is_not_empty should NOT match for non-array variables with the // same name - shell.set_variable("VARIABLE", VariableType::Str("notempty-variable".into())); + shell.set("VARIABLE", "notempty-variable".to_string()); assert_eq!(array_var_is_not_empty("VARIABLE", &shell), false); } @@ -386,16 +385,16 @@ fn test_array_var_is_not_empty() { fn test_string_var_is_not_empty() { let mut shell = shell::ShellBuilder::new().as_library(); - shell.set_variable("EMPTY", VariableType::Str("".into())); + shell.set("EMPTY", "".to_string()); assert_eq!(string_var_is_not_empty("EMPTY", &shell), false); - shell.set_variable("NOT_EMPTY", VariableType::Str("notempty".into())); + shell.set("NOT_EMPTY", "notempty".to_string()); assert_eq!(string_var_is_not_empty("NOT_EMPTY", &shell), true); // string_var_is_not_empty should NOT match for arrays with the same name - let mut vec = Vec::new(); - vec.push("not-empty".to_owned()); - shell.variables.set_variable("ARRAY_NOT_EMPTY", VariableType::Array(vec.into())); + let mut array = types::Array::new(); + array.push("not-empty".to_owned()); + shell.variables.set("ARRAY_NOT_EMPTY", array); assert_eq!(string_var_is_not_empty("ARRAY_NOT_EMPTY", &shell), false); // test for a variable which does not even exist @@ -420,9 +419,9 @@ fn test_function_is_defined() { statements.push(Statement::End); let description = "description".to_owned(); - shell.variables.set_variable( + shell.variables.set( &name, - VariableType::Function(Function::new(Some(description), name.clone(), args, statements)), + Function::new(Some(description), name.clone(), args, statements), ); assert_eq!(function_is_defined(name_str, &shell), true); diff --git a/src/lib/builtins/is.rs b/src/lib/builtins/is.rs index e862eaa3a2ff450ada4d2fe42eba75c11262f761..b191e970870577eda4332702bf8edeacee49d01d 100644 --- a/src/lib/builtins/is.rs +++ b/src/lib/builtins/is.rs @@ -1,6 +1,3 @@ -#[cfg(test)] -use shell::variables::VariableType; - use shell::Shell; use types; @@ -47,8 +44,8 @@ fn test_is() { } use shell::ShellBuilder; let mut shell = ShellBuilder::new().as_library(); - shell.set_variable("x", VariableType::Str("value".into())); - shell.set_variable("y", VariableType::Str("0".into())); + shell.set("x", "value".to_string()); + shell.set("y", "0".to_string()); // Four arguments assert_eq!( diff --git a/src/lib/builtins/set.rs b/src/lib/builtins/set.rs index 556d215be77ec766cb52746482710138f781d10c..98446b69dc98e9db1c115b6aceacb5e0b86c31af 100644 --- a/src/lib/builtins/set.rs +++ b/src/lib/builtins/set.rs @@ -1,5 +1,5 @@ use liner::KeyBindings; -use shell::{flags::*, variables::VariableType, Shell}; +use shell::{flags::*, Shell}; use types; use std::iter; @@ -79,13 +79,13 @@ pub(crate) fn set(args: &[String], shell: &mut Shell) -> i32 { // This used to take a `&[String]` but cloned them all, so although // this is non-ideal and could probably be better done with `Rc`, it // hasn't got any slower. - let arguments = iter::once(command) + let arguments: types::Array = iter::once(command) .chain(args_iter.map(|i| i.to_string())) .collect(); match kind { - UnsetIfNone => { shell.variables.set_variable("args", VariableType::Array(arguments)); } + UnsetIfNone => { shell.variables.set("args", arguments); } RetainIfNone => if arguments.len() != 1 { - shell.variables.set_variable("args", VariableType::Array(arguments)); + shell.variables.set("args", arguments); }, } } diff --git a/src/lib/builtins/variables.rs b/src/lib/builtins/variables.rs index 0792850db964372c8b11558a3b24a019dee1825a..98fc23a0c93a7d92d3f3e1b124be3a6e5fa302a0 100644 --- a/src/lib/builtins/variables.rs +++ b/src/lib/builtins/variables.rs @@ -2,7 +2,7 @@ use std::io::{self, Write}; -use shell::{status::*, variables::{Variables, VariableType}}; +use shell::{status::*, variables::Variables}; use types::*; fn print_list(vars: &Variables) { @@ -74,7 +74,7 @@ pub(crate) fn alias(vars: &mut Variables, args: &str) -> i32 { return FAILURE; } Binding::KeyValue(key, value) => { - vars.set_variable(&key, VariableType::Alias(Alias(value))); + vars.set(&key, Alias(value)); } Binding::ListEntries => print_list(&vars), Binding::KeyOnly(key) => { @@ -177,7 +177,7 @@ mod test { #[test] fn drop_deletes_variable() { let mut variables = Variables::default(); - variables.set_variable("FOO", VariableType::Str("BAR".into())); + variables.set("FOO", "BAR".to_string()); let return_status = drop_variable(&mut variables, &["drop", "FOO"]); assert_eq!(SUCCESS, return_status); let expanded = expand_string("$FOO", &VariableExpander(variables), false).join(""); @@ -201,7 +201,7 @@ mod test { #[test] fn drop_deletes_array() { let mut variables = Variables::default(); - variables.set_variable("FOO", VariableType::Array(array!["BAR"])); + variables.set("FOO", array!["BAR"]); let return_status = drop_array(&mut variables, &["drop", "-a", "FOO"]); assert_eq!(SUCCESS, return_status); let expanded = expand_string("@FOO", &VariableExpander(variables), false).join(""); diff --git a/src/lib/parser/loops.rs b/src/lib/parser/loops.rs index c5d23f6db0dcff167568156c880f4d32ff958886..6161a3ed4e67cad22d448f750a1766e0754fb54d 100644 --- a/src/lib/parser/loops.rs +++ b/src/lib/parser/loops.rs @@ -65,7 +65,7 @@ impl ForExpression { #[cfg(test)] mod tests { use super::*; - use shell::variables::{Variables, VariableType}; + use shell::variables::Variables; struct VariableExpander(pub Variables); @@ -112,7 +112,7 @@ mod tests { #[test] fn for_variable() { let mut variables = Variables::default(); - variables.set_variable("A", VariableType::Str("1 2 3 4 5".into())); + variables.set("A", "1 2 3 4 5".to_string()); assert_eq!( ForExpression::new(&["$A".to_owned()], &VariableExpander(variables)), ForExpression::Normal("1 2 3 4 5".to_owned()) diff --git a/src/lib/shell/assignments.rs b/src/lib/shell/assignments.rs index e27f8b8c873bb3defaeb125d0b52a5ec0457c469..0fad4fe729df9db191a3d2912ed36af0da493afe 100644 --- a/src/lib/shell/assignments.rs +++ b/src/lib/shell/assignments.rs @@ -269,7 +269,7 @@ impl VariableStore for Shell { match collected.remove(key.name) { map @ Some(VariableType::HashMap(_)) => { if let Primitive::HashMap(_) = key.kind { - self.variables.set_variable(key.name, map.unwrap()); + self.variables.set(key.name, map.unwrap()); } else if let Primitive::Indexed(_, _) = key.kind { eprintln!("ion: cannot insert hash map into index"); return FAILURE; @@ -280,7 +280,7 @@ impl VariableStore for Shell { eprintln!("ion: multi-dimensional arrays are not yet supported"); return FAILURE; } else { - self.variables.set_variable(key.name, array.unwrap()); + self.variables.set(key.name, array.unwrap()); } } Some(VariableType::Str(value)) => { @@ -329,8 +329,8 @@ impl VariableStore for Shell { } Ok(Action::UpdateString(key, _, _)) => { match collected.remove(key.name) { - str_ @ Some(VariableType::Str(_)) => { self.variables.set_variable(key.name, str_.unwrap()); } - array @ Some(VariableType::Array(_)) => { self.variables.set_variable(key.name, array.unwrap()); } + str_ @ Some(VariableType::Str(_)) => { self.variables.set(key.name, str_.unwrap()); } + array @ Some(VariableType::Array(_)) => { self.variables.set(key.name, array.unwrap()); } _ => () } } diff --git a/src/lib/shell/binary/mod.rs b/src/lib/shell/binary/mod.rs index df279112790a8b41a5eee05f851af1609ceffeb7..03bce01ed8de7f7bc7dbfce236e696bb7e5ebd35 100644 --- a/src/lib/shell/binary/mod.rs +++ b/src/lib/shell/binary/mod.rs @@ -8,7 +8,7 @@ use self::{ prompt::{prompt, prompt_fn}, readln::readln, terminate::{terminate_quotes, terminate_script_quotes}, }; -use super::{flow_control::Statement, status::*, variables::VariableType, FlowLogic, Shell, ShellHistory}; +use super::{flow_control::Statement, status::*, FlowLogic, Shell, ShellHistory}; use types; use liner::{Buffer, Context}; use std::{env, fs::File, io::ErrorKind, iter, path::Path, process, sync::Mutex}; @@ -128,7 +128,7 @@ impl Binary for Shell { self.evaluate_init_file(); self.variables - .set_variable("args", VariableType::Array(iter::once(env::args().next().unwrap()).collect())); + .set("args", iter::once(env::args().next().unwrap()).collect::<types::Array>()); loop { if let Some(command) = self.readln() { diff --git a/src/lib/shell/flow.rs b/src/lib/shell/flow.rs index 5ea0442509a519df5da5b569f052834faa019c1d..5a6df96df07bf6c3acb02afed325ea2f74cee40e 100644 --- a/src/lib/shell/flow.rs +++ b/src/lib/shell/flow.rs @@ -89,11 +89,11 @@ impl FlowLogic for Shell { // Execute a Let Statement Statement::Let(action) => { self.previous_status = self.local(action); - self.variables.set_variable("?", VariableType::Str(self.previous_status.to_string())); + self.variables.set("?", self.previous_status.to_string()); } Statement::Export(action) => { self.previous_status = self.export(action); - self.variables.set_variable("?", VariableType::Str(self.previous_status.to_string())); + self.variables.set("?", self.previous_status.to_string()); } // Collect the statements for the while loop, and if the loop is complete, // execute the while loop with the provided expression. @@ -192,9 +192,9 @@ impl FlowLogic for Shell { if self.flow_control.level == 0 { // All blocks were read, thus we can add it to the list - self.variables.set_variable( + self.variables.set( &name, - VariableType::Function(Function::new(description, name.clone(), args, statements)), + Function::new(description, name.clone(), args, statements), ); } else { // Store the partial function declaration in memory. @@ -294,7 +294,7 @@ impl FlowLogic for Shell { _ => (), } let status = self.previous_status.to_string(); - self.set_variable("?", VariableType::Str(status)); + self.set("?", status); } else { // A statement wasn't executed , which means that current_statement has been // set to the inner statement. We fix this here. @@ -370,7 +370,7 @@ impl FlowLogic for Shell { } }, ForExpression::Multiple(values) => for value in &values { - self.set_variable(variable, VariableType::Str(value.clone())); + self.set(variable, value.clone()); match self.execute_statements(statements.clone()) { Condition::Break => break, Condition::SigInt => return Condition::SigInt, @@ -385,7 +385,7 @@ impl FlowLogic for Shell { } }, ForExpression::Normal(values) => for value in values.lines() { - self.set_variable(variable, VariableType::Str(value.into())); + self.set(variable, value.to_string()); match self.execute_statements(statements.clone()) { Condition::Break => break, Condition::SigInt => return Condition::SigInt, @@ -400,7 +400,7 @@ impl FlowLogic for Shell { } }, ForExpression::Range(start, end) => for value in (start..end).map(|x| x.to_string()) { - self.set_variable(variable, VariableType::Str(value.clone())); + self.set(variable, value.clone()); match self.execute_statements(statements.clone()) { Condition::Break => break, Condition::SigInt => return Condition::SigInt, @@ -431,11 +431,11 @@ impl FlowLogic for Shell { Statement::Error(number) => self.previous_status = number, Statement::Let(action) => { self.previous_status = self.local(action); - self.variables.set_variable("?", VariableType::Str(self.previous_status.to_string())); + self.variables.set("?", self.previous_status.to_string()); } Statement::Export(action) => { self.previous_status = self.export(action); - self.variables.set_variable("?", VariableType::Str(self.previous_status.to_string())); + self.variables.set("?", self.previous_status.to_string()); } Statement::While { expression, @@ -494,9 +494,9 @@ impl FlowLogic for Shell { } => { self.flow_control.level += 1; collect_loops(&mut iterator, &mut statements, &mut self.flow_control.level); - self.variables.set_variable( + self.variables.set( &name, - VariableType::Function(Function::new(description, name.clone(), args, statements)), + Function::new(description, name.clone(), args, statements), ); } Statement::Pipeline(mut pipeline) => { @@ -569,8 +569,7 @@ impl FlowLogic for Shell { SUCCESS => self.previous_status = FAILURE, _ => (), } - let status = self.previous_status.to_string(); - self.set_variable("?", VariableType::Str(status)); + self.set("?", self.previous_status.to_string()); } Statement::Break => return Condition::Break, Statement::Continue => return Condition::Continue, @@ -658,13 +657,13 @@ impl FlowLogic for Shell { .variables .get::<types::Array>(bind) .map(|x| VariableType::Array(x)); - self.variables.set_variable(&bind, VariableType::Array(value.clone())); + self.variables.set(&bind, value.clone()); } else { previous_bind = self .variables .get::<types::Value>(bind) .map(|x| VariableType::Str(x)); - self.set_variable(&bind, VariableType::Str(value.join(" ").into())); + self.set(&bind, value.join(" ").to_string()); } } @@ -680,9 +679,9 @@ impl FlowLogic for Shell { if let Some(ref bind) = case.binding { if let Some(value) = previous_bind { match value { - str_ @ VariableType::Str(_) => { self.set_variable(bind, str_); } - array @ VariableType::Array(_) => { self.variables.set_variable(bind, array); } - map @ VariableType::HashMap(_) => { self.variables.set_variable(bind, map); } + str_ @ VariableType::Str(_) => { self.set(bind, str_); } + array @ VariableType::Array(_) => { self.variables.set(bind, array); } + map @ VariableType::HashMap(_) => { self.variables.set(bind, map); } _ => (), } } @@ -698,13 +697,13 @@ impl FlowLogic for Shell { .variables .get::<types::Array>(bind) .map(|x| VariableType::Array(x)); - self.variables.set_variable(&bind, VariableType::Array(value.clone())); + self.variables.set(&bind, value.clone()); } else { previous_bind = self .variables .get::<types::Value>(bind) .map(|x| VariableType::Str(x)); - self.set_variable(&bind, VariableType::Str(value.join(" ").into())); + self.set(&bind, value.join(" ").to_string()); } } @@ -720,9 +719,9 @@ impl FlowLogic for Shell { if let Some(ref bind) = case.binding { if let Some(value) = previous_bind { match value { - str_ @ VariableType::Str(_) => { self.set_variable(bind, str_); } - array @ VariableType::Array(_) => { self.set_variable(bind, array); } - map @ VariableType::HashMap(_) => { self.set_variable(bind, map); } + str_ @ VariableType::Str(_) => { self.set(bind, str_); } + array @ VariableType::Array(_) => { self.set(bind, array); } + map @ VariableType::HashMap(_) => { self.set(bind, map); } _ => (), } } @@ -845,11 +844,11 @@ impl FlowLogic for Shell { Statement::Error(number) => shell.previous_status = number, Statement::Let(action) => { shell.previous_status = shell.local(action); - shell.variables.set_variable("?", VariableType::Str(shell.previous_status.to_string())); + shell.variables.set("?", shell.previous_status.to_string()); } Statement::Export(action) => { shell.previous_status = shell.export(action); - shell.variables.set_variable("?", VariableType::Str(shell.previous_status.to_string())); + shell.variables.set("?", shell.previous_status.to_string()); } Statement::While { expression, @@ -876,9 +875,9 @@ impl FlowLogic for Shell { statements, description, } => { - shell.variables.set_variable( + shell.variables.set( &name, - VariableType::Function(Function::new(description, name.clone(), args, statements)), + Function::new(description, name.clone(), args, statements), ); } Statement::If { @@ -931,7 +930,7 @@ impl FlowLogic for Shell { } shell .variables - .set_variable("?", VariableType::Str(shell.previous_status.to_string())); + .set("?", shell.previous_status.to_string()); } _ => (), } diff --git a/src/lib/shell/fork.rs b/src/lib/shell/fork.rs index df7a513edc9d87ea606d349ad8adc2976f5720dc..82670a33085537c65d58157b327d1f9aaa53de01 100644 --- a/src/lib/shell/fork.rs +++ b/src/lib/shell/fork.rs @@ -1,4 +1,4 @@ -use super::{variables::VariableType, IonError, Shell}; +use super::{IonError, Shell}; use std::{ fs::File, io, @@ -130,7 +130,7 @@ impl<'a> Fork<'a> { // Obtain ownership of the child's copy of the shell, and then configure it. let mut shell: Shell = unsafe { (self.shell as *const Shell).read() }; - shell.set_variable("PID", VariableType::Str(sys::getpid().unwrap_or(0).to_string())); + shell.set("PID", sys::getpid().unwrap_or(0).to_string()); let _ = shell.context.take(); // Execute the given closure within the child's shell. diff --git a/src/lib/shell/mod.rs b/src/lib/shell/mod.rs index 03b5dc9dc5b77cb638cc7cde05da94347c4703de..43ff0389bf4090a08db483d9b7a218733368b880 100644 --- a/src/lib/shell/mod.rs +++ b/src/lib/shell/mod.rs @@ -236,8 +236,8 @@ impl Shell { } /// Sets a variable of `name` with the given `value` in the shell's variable map. - pub fn set_variable(&mut self, name: &str, value: VariableType) { - self.variables.set_variable(name, value); + pub fn set<T: Into<VariableType>>(&mut self, name: &str, value: T) { + self.variables.set(name, value); } /// Executes a pipeline and returns the final exit status of the pipeline. @@ -337,7 +337,7 @@ impl Shell { // Retrieve the exit_status and set the $? variable and history.previous_status if let Some(code) = exit_status { - self.set_variable("?", VariableType::Str(code.to_string())); + self.set("?", code.to_string()); self.previous_status = code; } diff --git a/src/lib/shell/variables/mod.rs b/src/lib/shell/variables/mod.rs index 34548dd22549259a9ef8deca4ef738c771ff3f60..f71a32141bcdc16c32655eb19b32d346b05250f9 100644 --- a/src/lib/shell/variables/mod.rs +++ b/src/lib/shell/variables/mod.rs @@ -82,6 +82,36 @@ impl From<VariableType> for Function { } } +impl From<String> for VariableType { + fn from(string: String) -> Self { + VariableType::Str(string) + } +} + +impl From<Alias> for VariableType { + fn from(alias: Alias) -> Self { + VariableType::Alias(alias) + } +} + +impl From<Array> for VariableType { + fn from(array: Array) -> Self { + VariableType::Array(array) + } +} + +impl From<HashMap> for VariableType { + fn from(hash_map: HashMap) -> Self { + VariableType::HashMap(hash_map) + } +} + +impl From<Function> for VariableType { + fn from(function: Function) -> Self { + VariableType::Function(function) + } +} + impl fmt::Display for VariableType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -488,7 +518,8 @@ impl Variables { } } - pub fn set_variable(&mut self, name: &str, var: VariableType) { + pub fn set<T: Into<VariableType>>(&mut self, name: &str, var: T) { + let var = var.into(); match self.lookup_any_mut(&name) { Some(VariableType::Str(ref mut str_)) => { if !name.is_empty() { @@ -658,7 +689,7 @@ impl Variables { for arg in args.into_iter().skip(1) { match con.read_line(format!("{}=", arg.as_ref().trim()), None, &mut |_| {}) { Ok(buffer) => { - self.set_variable(arg.as_ref(), VariableType::Str(buffer.trim().into())); + self.set(arg.as_ref(), buffer.trim().to_string()); } Err(_) => return FAILURE, } @@ -669,7 +700,7 @@ impl Variables { let mut lines = handle.lines(); for arg in args.into_iter().skip(1) { if let Some(Ok(line)) = lines.next() { - self.set_variable(arg.as_ref(), VariableType::Str(line.trim().into())); + self.set(arg.as_ref(), line.trim().to_string()); } } } @@ -706,7 +737,7 @@ mod tests { #[test] fn set_var_and_expand_a_variable() { let mut variables = Variables::default(); - variables.set_variable("FOO", VariableType::Str("BAR".into())); + variables.set("FOO", "BAR".to_string()); let expanded = expand_string("$FOO", &VariableExpander(variables), false).join(""); assert_eq!("BAR", &expanded); } diff --git a/src/main.rs b/src/main.rs index 32e45f72dd2ad4a8311420690e3ca1b4690f7ef0..27314b929b10451fa18b6852f229ede7063cb07c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ extern crate ion_shell; extern crate ion_sys as sys; extern crate smallvec; -use ion_shell::{flags::NO_EXEC, shell::variables::VariableType, Binary, JobControl, ShellBuilder, MAN_ION}; +use ion_shell::{flags::NO_EXEC, Binary, JobControl, ShellBuilder, MAN_ION}; use smallvec::SmallVec; use std::{ env, error::Error, io::{stdout, stdin, Write, BufRead, BufReader}, iter::FromIterator, @@ -45,7 +45,7 @@ fn main() { for arg in args { array.push(arg.into()); } - shell.variables.set_variable("args", VariableType::Array(array)); + shell.variables.set("args", array); if let Err(err) = shell.execute_script(&path) { eprintln!("ion: {}", err); }