1 use super::Status;
2 use crate as ion_shell;
3 use crate::{shell::Shell, types};
4 use builtins_proc::builtin;
5
6 // TODO: Add support for multiple name in builtins man
7 #[builtin(
8 names = "eq, is",
9 desc = "checks if two arguments are the same",
10 man = "
11 SYNOPSIS
12 is [ -h | --help ] [not]
13
14 DESCRIPTION
15 Returns 0 if the two arguments are equal
16
17 OPTIONS
18 not
19 returns 0 if the two arguments are not equal."
20 )]
is(args: &[types::Str], shell: &mut Shell<'_>) -> Status21 pub fn is(args: &[types::Str], shell: &mut Shell<'_>) -> Status {
22 match args.len() {
23 4 => {
24 if args[1] != "not" {
25 return Status::error(format!("Expected 'not' instead found '{}'", args[1]));
26 } else if eval_arg(&*args[2], shell) == eval_arg(&*args[3], shell) {
27 return Status::error("");
28 }
29 }
30 3 => {
31 if eval_arg(&*args[1], shell) != eval_arg(&*args[2], shell) {
32 return Status::error("");
33 }
34 }
35 _ => return Status::error("is needs 3 or 4 arguments"),
36 }
37
38 Status::SUCCESS
39 }
40
eval_arg(arg: &str, shell: &mut Shell<'_>) -> types::Str41 fn eval_arg(arg: &str, shell: &mut Shell<'_>) -> types::Str {
42 if let Some(value) = get_var_string(arg, shell) {
43 value
44 } else {
45 arg.into()
46 }
47 }
48
49 // On error returns an empty String.
get_var_string(name: &str, shell: &mut Shell<'_>) -> Option<types::Str>50 fn get_var_string(name: &str, shell: &mut Shell<'_>) -> Option<types::Str> {
51 if name.chars().nth(0)? != '$' {
52 return None;
53 }
54
55 match shell.variables().get_str(&name[1..]) {
56 Ok(s) => Some(s),
57 Err(why) => {
58 eprintln!("{}", why);
59 None
60 }
61 }
62 }
63
64 #[test]
test_is()65 fn test_is() {
66 fn vec_string(args: &[&str]) -> Vec<types::Str> { args.iter().map(|&s| s.into()).collect() }
67 let mut shell = Shell::default();
68 shell.variables_mut().set("x", "value");
69 shell.variables_mut().set("y", "0");
70
71 // Four arguments
72 assert!(builtin_is(&vec_string(&["is", " ", " ", " "]), &mut shell).is_failure());
73 assert!(builtin_is(&vec_string(&["is", "not", " ", " "]), &mut shell).is_failure());
74 assert!(builtin_is(&vec_string(&["is", "not", "$x", "$x"]), &mut shell).is_failure());
75 assert!(builtin_is(&vec_string(&["is", "not", "2", "1"]), &mut shell).is_success());
76 assert!(builtin_is(&vec_string(&["is", "not", "$x", "$y"]), &mut shell).is_success());
77
78 // Three arguments
79 assert!(builtin_is(&vec_string(&["is", "1", "2"]), &mut shell).is_failure());
80 assert!(builtin_is(&vec_string(&["is", "$x", "$y"]), &mut shell).is_failure());
81 assert!(builtin_is(&vec_string(&["is", " ", " "]), &mut shell).is_success());
82 assert!(builtin_is(&vec_string(&["is", "$x", "$x"]), &mut shell).is_success());
83
84 // Two arguments
85 assert!(builtin_is(&vec_string(&["is", " "]), &mut shell).is_failure());
86
87 // One argument
88 assert!(builtin_is(&vec_string(&["is"]), &mut shell).is_failure());
89 }
90