pub fn execute(
        self,
        shell: &mut Shell,
    ) -> Result<i32, ShellError> {

        match self {
            Construct::For {loop_var, iterable, code} => {
                let mut status: i32 = 0;

                for item in iterable {
                    shell.add_variable(&loop_var, Variable::from(item));
                    //* clone here slows things down a lot
                    let code2 = code.clone();
                    for block in code2 {
                        status = block.execute(shell)?;
                    }
                }
                shell.remove_variable(&loop_var);
                Ok(status)
            }
            Construct::While{condition, code} => {
                let mut status: i32 = 0;

                while eval_condition(shell, condition.clone())? {
                    let code2 = code.clone();
                    for block in code2 {
                        status = block.execute(shell)?;
                    }
                }

                Ok(status)
            }
            Construct::If {conditions, mut code} => {
                let mut status: i32 = 0;
                if code.is_empty() {
                    return Ok(0)
                }
                //note: this isn't particularly efficient
                for (condition, _execif) in conditions {
                    //for every if and elif
                    let to_exec = code.remove(0);
                    //if execif is true, execute the code block
                    if eval_condition(shell, condition)? {
                        for job in to_exec {
                            status = job.execute(shell)?;
                        }
                        return Ok(status)
                    }
                }
                //we have reached the else statement
                //at this point there should only be one item left in code
                //if code is empty, there is no else clause
                if code.len() == 1 {
                    let to_exec = code.remove(0);
                    for job in to_exec {
                        status = job.execute(shell)?;
                    }
                } else if code.len() > 1 {
                    return Err(
                        ShellError::from("error: code and condition mismatch")
                    )
                }
                Ok(status) //code is empty
            }
            //Base case
            Construct::Code(code) => {
                // for (key, value) in vars {
                //     shell.add_variable(&key, &value);
                // }
                let (status, _cap) = execute_jobs(shell, code, false)?;
                Ok(status)
            }
        }
    }
/// Recursively executes itself, consuming itself as it goes.
Recursively executes itself, consuming itself as it goes.
Recursively executes itself consuming itself as it goes .
pub fn execute(
        self,
        shell: &mut Shell,
    ) -> Result<i32, ShellError> {
        match self {
            Construct::For {loop_var, iterable, code} => {
                let mut status: i32 = 0;
                for item in iterable {
                    shell.add_variable(&loop_var, Variable::from(item));
                    //* clone here slows things down a lot
                    let code2 = code.clone();
                    for block in code2 {
                        status = block.execute(shell)?;
                    }
                }
                shell.remove_variable(&loop_var);
                Ok(status)
            }
            Construct::While{condition, code} => {
                let mut status: i32 = 0;
                while eval_condition(shell, condition.clone())? {
                    let code2 = code.clone();
                    for block in code2 {
                        status = block.execute(shell)?;
                    }
                }
                Ok(status)
            }
            Construct::If {conditions, mut code} => {
                let mut status: i32 = 0;
                if code.is_empty() {
                    return Ok(0)
                }
                //note: this isn't particularly efficient
                for (condition, _execif) in conditions {
                    //for every if and elif
                    let to_exec = code.remove(0);
                    //if execif is true, execute the code block
                    if eval_condition(shell, condition)? {
                        for job in to_exec {
                            status = job.execute(shell)?;
                        }
                        return Ok(status)
                    }
                }
                //we have reached the else statement
                //at this point there should only be one item left in code
                //if code is empty, there is no else clause
                if code.len() == 1 {
                    let to_exec = code.remove(0);
                    for job in to_exec {
                        status = job.execute(shell)?;
                    }
                } else if code.len() > 1 {
                    return Err(
                        ShellError::from("error: code and condition mismatch")
                    )
                }
                Ok(status) //code is empty
            }
            //Base case
            Construct::Code(code) => {
                // for (key, value) in vars {
                //     shell.add_variable(&key, &value);
                // }
                let (status, _cap) = execute_jobs(shell, code, false)?;
                Ok(status)
            }
        }
    }
pub fn execute ( self , shell : & mut Shell , ) -> Result < i32 , ShellError > { match self { Construct :: For { loop_var , iterable , code } => { let mut status : i32 = 0 ; for item in iterable { shell . add_variable ( & loop_var , Variable :: from ( item ) ) ; //* clone here slows things down a lot let code2 = code . clone ( ) ; for block in code2 { status = block . execute ( shell ) ? ; } } shell . remove_variable ( & loop_var ) ; Ok ( status ) } Construct :: While { condition , code } => { let mut status : i32 = 0 ; while eval_condition ( shell , condition . clone ( ) ) ? { let code2 = code . clone ( ) ; for block in code2 { status = block . execute ( shell ) ? ; } } Ok ( status ) } Construct :: If { conditions , mut code } => { let mut status : i32 = 0 ; if code . is_empty ( ) { return Ok ( 0 ) } //note: this isn't particularly efficient for ( condition , _execif ) in conditions { //for every if and elif let to_exec = code . remove ( 0 ) ; //if execif is true, execute the code block if eval_condition ( shell , condition ) ? { for job in to_exec { status = job . execute ( shell ) ? ; } return Ok ( status ) } } //we have reached the else statement //at this point there should only be one item left in code //if code is empty, there is no else clause if code . len ( ) == 1 { let to_exec = code . remove ( 0 ) ; for job in to_exec { status = job . execute ( shell ) ? ; } } else if code . len ( ) > 1 { return Err ( ShellError :: from ( " " ) ) } Ok ( status ) //code is empty } //Base case Construct :: Code ( code ) => { // for (key, value) in vars { //     shell.add_variable(&key, &value); // } let ( status , _cap ) = execute_jobs ( shell , code , false ) ? ; Ok ( status ) } } }
Recursively executes itself, consuming itself as it goes.
Recursively executes itself consuming itself as it goes .
self
shell
&mut Shell