igo-rs 0.3.0

Pure Rust port of the Igo, a POS(Part-Of-Speech) tagger for Japanese (日本語 形態素解析).
Documentation
use std::env;
use std::io::{self, BufRead};
use std::path::PathBuf;

use getopts::Options;
//use igo::Morpheme;
use log::info;

use igo::Tagger;

fn print_usage(program: &str, opts: Options) {
    println!("{}", opts.usage(&format!("Usage:\n {} [options] <dictionary directory>", program)));
}

fn print_result(tagger: &Tagger, wakati: bool, text: &str) {
    info!("text: {}", text);
    if wakati {
        // std::slice::SliceConcatExt はUnstable
        for w in &tagger.wakati(text) {
            print!("{} ", w);
        }
        println!();
    } else {
        for m in &tagger.parse(text) {
            println!("{}\t{}", m.surface, m.feature);
        }
        println!("EOS");
    }
}

fn igo_stdin(tagger: Tagger, wakati: bool) {
    let stdin = io::stdin();
    let mut line = String::new();
    loop {
        line.clear();
        stdin.lock().read_line(&mut line).expect("Could not read line");
        let text = line.trim();

        if !text.is_empty() {
            print_result(&tagger, wakati, text);
        } else {
            return;
        }
    }
}

fn igo_cli() -> i32 {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();

    let mut opts = Options::new();
    opts.optopt("t", "text", "use TEXT as input, instead of STDIN", "TEXT");
    opts.optflag("w", "wakati", "enable wakati-gaki mode");
    opts.optflag("v", "verbose", "enable verbose mode.");
    opts.optflag("", "help", "show this usage message.");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(_) => {
            print_usage(&program, opts);
            return 1;
        }
    };
    if matches.opt_present("help") {
        print_usage(&program, opts);
        return 1;
    }
    if matches.opt_present("verbose") {
        simple_logger::init().unwrap();
    }
    let dic_dir = if !matches.free.is_empty() {
        PathBuf::from(matches.free[0].clone())
    } else {
        print_usage(&program, opts);
        return 1;
    };

    let tagger = Tagger::new(&dic_dir).expect("Failed to initialize Tagger");
    info!("tagger loaded");
    let wakati_flag = matches.opt_present("wakati");
    match matches.opt_str("t") {
        Some(text) => print_result(&tagger, wakati_flag, &text),
        None => igo_stdin(tagger, wakati_flag)
    }

    0
}

fn main() {
    std::process::exit(igo_cli())
}