cicada 0.7.2

A simple Unix shell.
Documentation
use std::io::Write;
use std::path::Path;

use sqlite;
use sqlite::State;

use history;
use parsers;

pub fn run(tokens: &Vec<(String, String)>) -> i32 {
    let args = parsers::parser_line::tokens_to_args(&tokens);
    let hfile = history::get_history_file();
    let path = Path::new(hfile.as_str());
    if !path.exists() {
        println_stderr!("no history file.");
        return 1;
    }

    if let Ok(conn) = sqlite::open(hfile.clone()) {
        if args.len() == 1 {
            return list_current_history(&conn);
        } else if args.len() == 2 {
            search_history(&conn, args[1].as_str());
        } else {
            println_stderr!("history: only take one arg");
        }
    } else {
        println_stderr!("history: history file open error.");
        return 1;
    }
    0
}

fn list_current_history(conn: &sqlite::Connection) -> i32 {
    let history_table = history::get_history_table();
    let q = format!(
        "SELECT inp FROM {} ORDER BY tsb desc limit 10;",
        history_table
    );
    match conn.prepare(q) {
        Ok(mut statement) => {
            let mut vec = Vec::new();
            loop {
                match statement.next() {
                    Ok(x) => {
                        if let State::Row = x {
                            if let Ok(_x) = statement.read::<String>(0) {
                                vec.push(_x);
                            }
                        } else {
                            break;
                        }
                    }
                    Err(e) => {
                        println_stderr!("history: statement.next error: {:?}", e);
                        return 1;
                    }
                }
            }

            for (i, elem) in vec.iter().rev().enumerate() {
                println!("{}: {}", i, elem);
            }
        }
        Err(e) => {
            println_stderr!("history: prepare error - {:?}", e);
            return 1;
        }
    }
    0
}

fn search_history(conn: &sqlite::Connection, q: &str) {
    let history_table = history::get_history_table();
    let q = format!(
        "SELECT inp FROM {}
                     WHERE inp like '%{}%'
                     ORDER BY tsb desc limit 20;",
        history_table,
        q
    );
    match conn.prepare(q) {
        Ok(mut statement) => {
            let mut vec = Vec::new();
            loop {
                match statement.next() {
                    Ok(x) => {
                        if let State::Row = x {
                            if let Ok(_x) = statement.read::<String>(0) {
                                vec.push(_x);
                            }
                        } else {
                            break;
                        }
                    }
                    Err(e) => {
                        println_stderr!("history: statement.next error: {:?}", e);
                        return;
                    }
                }
            }
            for (i, elem) in vec.iter().rev().enumerate() {
                println!("{}: {}", i, elem);
            }
        }
        Err(e) => {
            println_stderr!("history: prepare error - {:?}", e);
        }
    }
}