fn split_on_branches(raw: Vec<Job>) 
             //condition    codeblock  
-> Result<Vec<(Option<(Job, bool)>, Vec<Job>)>, ShellError> {
    let mut to_return = Vec::<(Option<(Job, bool)>, Vec<Job>)>::new();
    let mut buffer = Vec::new();
    let mut nesting_level: isize = -1;
    let mut condition = None;
    let mut raw = raw.into_iter();
    while let Some(job) = raw.next() {
        match job.cmds[0].cmd.1.as_str() {
            "for" | "while" => {
                buffer.push(job);
                nesting_level += 1;
            }
            "if" => { 
                nesting_level += 1;
                if job.cmds[0].args.len() < 2 {
                    return Err(ShellError::from("oyster: syntax error (no condition)"))
                }
                if nesting_level == 0 {
                    let command = if job.cmds[0].args[1].1.starts_with("!") {
                        (
                            job.cmds[0].args[1].0, 
                            job.cmds[0].args[1].1[1..].to_string()
                        )
                    } else {
                        job.cmds[0].args[1].clone()
                    };
                    condition = Some((Job {
                        cmds: vec![TokenCmd {
                            cmd: command,
                            args: job.cmds[0].args[1..].to_vec(),
                            redirects: job.cmds[0].redirects.clone(),
                            pipe_stderr: job.cmds[0].pipe_stderr,
                        }],
                        execnext: job.execnext,
                        id: job.id,
                        },
                        !job.cmds[0].args[1].1.starts_with("!"))
                    );
                } else {
                    buffer.push(job);
                }
            }
            "elif" => {
                if job.cmds[0].args.len() < 2 {
                    return Err(ShellError::from("oyster: syntax error (no condition)"))
                }
                if nesting_level == 0 {
                    if job == Job::default() {
                        return Err(
                            ShellError::from(
                                "oyster: syntax error near `elif`"
                            )
                        )
                    }
                    to_return.push(
                        (condition.clone(), 
                        buffer.clone()));
                    buffer.clear();
                    let command = if job.cmds[0].args[1].1.starts_with("!") {
                        (
                            job.cmds[0].args[1].0, 
                            job.cmds[0].args[1].1[1..].to_string()
                        )
                    } else {
                        job.cmds[0].args[1].clone()
                    };
                    condition = Some((Job {
                        cmds: vec![TokenCmd {
                            cmd: command,
                            args: job.cmds[0].args[1..].to_vec(),
                            redirects: job.cmds[0].redirects.clone(),
                            pipe_stderr: job.cmds[0].pipe_stderr,
                        }],
                        execnext: job.execnext,
                        id: job.id,
                        },
                        !job.cmds[0].args[1].1.starts_with("!"))
                    );
                } else {
                    buffer.push(job);
                }
            }
            "else" => {
                if nesting_level == 0 {
                    to_return.push(
                        (condition.clone(), 
                        buffer.clone()));
                    buffer.clear();
                    condition = None;
                } else {
                    buffer.push(job);
                }
            }
            "done" => {
                buffer.push(job);
                nesting_level -= 1;
            }
            "end" => {
                if nesting_level == 0 {
                    to_return.push((condition.clone(), buffer.clone()));
                    buffer.clear();
                }
                nesting_level -= 1;
            }
            _ => {
                buffer.push(job);
            }
        }
    }
    if nesting_level > 0 {
        return Err(
            ShellError::from("oyster: parse error in if statement")
        )
    }
    //println!("{:?}", to_return);
    
    Ok(to_return)
}
/// Splits an if statement into if/elif/else blocks
//TODO: optimise this (i.e. remove clones `urgh`)
//TODO2: Fix ! condition
Splits an if statement into if/elif/else blocks
TODO: optimise this
TODO2: Fix . condition
Splits an if statement into if / elif / else blocks TODO : optimise this TODO2 : Fix . condition
fn split_on_branches(raw: Vec<Job>) 
             //condition    codeblock  
-> Result<Vec<(Option<(Job, bool)>, Vec<Job>)>, ShellError> {
    let mut to_return = Vec::<(Option<(Job, bool)>, Vec<Job>)>::new();
    let mut buffer = Vec::new();
    let mut nesting_level: isize = -1;
    let mut condition = None;
    let mut raw = raw.into_iter();
    while let Some(job) = raw.next() {
        match job.cmds[0].cmd.1.as_str() {
            "for" | "while" => {
                buffer.push(job);
                nesting_level += 1;
            }
            "if" => { 
                nesting_level += 1;
                if job.cmds[0].args.len() < 2 {
                    return Err(ShellError::from("oyster: syntax error (no condition)"))
                }
                if nesting_level == 0 {
                    let command = if job.cmds[0].args[1].1.starts_with("!") {
                        (
                            job.cmds[0].args[1].0, 
                            job.cmds[0].args[1].1[1..].to_string()
                        )
                    } else {
                        job.cmds[0].args[1].clone()
                    };
                    condition = Some((Job {
                        cmds: vec![TokenCmd {
                            cmd: command,
                            args: job.cmds[0].args[1..].to_vec(),
                            redirects: job.cmds[0].redirects.clone(),
                            pipe_stderr: job.cmds[0].pipe_stderr,
                        }],
                        execnext: job.execnext,
                        id: job.id,
                        },
                        !job.cmds[0].args[1].1.starts_with("!"))
                    );
                } else {
                    buffer.push(job);
                }
            }
            "elif" => {
                if job.cmds[0].args.len() < 2 {
                    return Err(ShellError::from("oyster: syntax error (no condition)"))
                }
                if nesting_level == 0 {
                    if job == Job::default() {
                        return Err(
                            ShellError::from(
                                "oyster: syntax error near `elif`"
                            )
                        )
                    }
                    to_return.push(
                        (condition.clone(), 
                        buffer.clone()));
                    buffer.clear();
                    let command = if job.cmds[0].args[1].1.starts_with("!") {
                        (
                            job.cmds[0].args[1].0, 
                            job.cmds[0].args[1].1[1..].to_string()
                        )
                    } else {
                        job.cmds[0].args[1].clone()
                    };
                    condition = Some((Job {
                        cmds: vec![TokenCmd {
                            cmd: command,
                            args: job.cmds[0].args[1..].to_vec(),
                            redirects: job.cmds[0].redirects.clone(),
                            pipe_stderr: job.cmds[0].pipe_stderr,
                        }],
                        execnext: job.execnext,
                        id: job.id,
                        },
                        !job.cmds[0].args[1].1.starts_with("!"))
                    );
                } else {
                    buffer.push(job);
                }
            }
            "else" => {
                if nesting_level == 0 {
                    to_return.push(
                        (condition.clone(), 
                        buffer.clone()));
                    buffer.clear();
                    condition = None;
                } else {
                    buffer.push(job);
                }
            }
            "done" => {
                buffer.push(job);
                nesting_level -= 1;
            }
            "end" => {
                if nesting_level == 0 {
                    to_return.push((condition.clone(), buffer.clone()));
                    buffer.clear();
                }
                nesting_level -= 1;
            }
            _ => {
                buffer.push(job);
            }
        }
    }
    if nesting_level > 0 {
        return Err(
            ShellError::from("oyster: parse error in if statement")
        )
    }
    //println!("{:?}", to_return);
    Ok(to_return)
}
fn split_on_branches ( raw : Vec < Job > ) //condition    codeblock   -> Result < Vec < ( Option < ( Job , bool ) > , Vec < Job > ) > , ShellError > { let mut to_return = Vec :: < ( Option < ( Job , bool ) > , Vec < Job > ) > :: new ( ) ; let mut buffer = Vec :: new ( ) ; let mut nesting_level : isize = - 1 ; let mut condition = None ; let mut raw = raw . into_iter ( ) ; while let Some ( job ) = raw . next ( ) { match job . cmds [ 0 ] . cmd . 1 . as_str ( ) { " " | " " => { buffer . push ( job ) ; nesting_level += 1 ; } " " => { nesting_level += 1 ; if job . cmds [ 0 ] . args . len ( ) < 2 { return Err ( ShellError :: from ( " " ) ) } if nesting_level == 0 { let command = if job . cmds [ 0 ] . args [ 1 ] . 1 . starts_with ( " " ) { ( job . cmds [ 0 ] . args [ 1 ] . 0 , job . cmds [ 0 ] . args [ 1 ] . 1 [ 1 .. ] . to_string ( ) ) } else { job . cmds [ 0 ] . args [ 1 ] . clone ( ) } ; condition = Some ( ( Job { cmds : vec ! [ TokenCmd { cmd command args job cmds [ 0 ] args [ 1 ] to_vec ( ) redirects job cmds [ 0 ] redirects clone ( ) pipe_stderr job cmds [ 0 ] pipe_stderr } ] , execnext : job . execnext , id : job . id , } , ! job . cmds [ 0 ] . args [ 1 ] . 1 . starts_with ( " " ) ) ) ; } else { buffer . push ( job ) ; } } " " => { if job . cmds [ 0 ] . args . len ( ) < 2 { return Err ( ShellError :: from ( " " ) ) } if nesting_level == 0 { if job == Job :: default ( ) { return Err ( ShellError :: from ( " " ) ) } to_return . push ( ( condition . clone ( ) , buffer . clone ( ) ) ) ; buffer . clear ( ) ; let command = if job . cmds [ 0 ] . args [ 1 ] . 1 . starts_with ( " " ) { ( job . cmds [ 0 ] . args [ 1 ] . 0 , job . cmds [ 0 ] . args [ 1 ] . 1 [ 1 .. ] . to_string ( ) ) } else { job . cmds [ 0 ] . args [ 1 ] . clone ( ) } ; condition = Some ( ( Job { cmds : vec ! [ TokenCmd { cmd command args job cmds [ 0 ] args [ 1 ] to_vec ( ) redirects job cmds [ 0 ] redirects clone ( ) pipe_stderr job cmds [ 0 ] pipe_stderr } ] , execnext : job . execnext , id : job . id , } , ! job . cmds [ 0 ] . args [ 1 ] . 1 . starts_with ( " " ) ) ) ; } else { buffer . push ( job ) ; } } " " => { if nesting_level == 0 { to_return . push ( ( condition . clone ( ) , buffer . clone ( ) ) ) ; buffer . clear ( ) ; condition = None ; } else { buffer . push ( job ) ; } } " " => { buffer . push ( job ) ; nesting_level -= 1 ; } " " => { if nesting_level == 0 { to_return . push ( ( condition . clone ( ) , buffer . clone ( ) ) ) ; buffer . clear ( ) ; } nesting_level -= 1 ; } _ => { buffer . push ( job ) ; } } } if nesting_level > 0 { return Err ( ShellError :: from ( " " ) ) } //println!("{:?}", to_return); Ok ( to_return ) }
Splits an if statement into if/elif/else blocks
TODO: optimise this (i.e.
Splits an if statement into if / elif / else blocks TODO : optimise this ( i . e .
raw
Vec<Job>