igo/dictionary/build/
mod.rs

1use std;
2use std::borrow::Cow;
3use std::convert::From;
4use std::error;
5use std::error::Error;
6use std::fmt;
7use std::fs;
8use std::io;
9use std::path::{Path, PathBuf};
10use std::time::Instant;
11
12use glob;
13use log::info;
14
15pub use self::charcategory::*;
16pub use self::worddic::*;
17
18mod worddic;
19mod charcategory;
20pub mod matrix;
21
22#[derive(Debug)]
23pub enum AppError {
24    Message(String),
25    Io(io::Error),
26    Parse {
27        message: String,
28        path: PathBuf,
29        line_number: i32,
30    },
31}
32
33pub type AppResult<T> = Result<T, AppError>;
34
35impl fmt::Display for AppError {
36    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37        match *self {
38            AppError::Message(ref err) => write!(f, "error: {}", err),
39            AppError::Io(ref err) => write!(f, "IO error: {}", err),
40            AppError::Parse { ref message, ref path, ref line_number } =>
41                write!(f, "{}\t{{file: {}, line: {}}}", message, path.display(), line_number),
42        }
43    }
44}
45
46impl error::Error for AppError {
47    fn description(&self) -> &str {
48        match *self {
49            AppError::Message(ref s) => s,
50            AppError::Io(ref err) => err.description(),
51            AppError::Parse { ref message, .. } => message,
52        }
53    }
54
55    fn cause(&self) -> Option<&dyn error::Error> {
56        match *self {
57            AppError::Message(_) | AppError::Parse { .. } => None,
58            AppError::Io(ref err) => Some(err),
59        }
60    }
61}
62
63impl From<String> for AppError {
64    fn from(e: String) -> Self {
65        AppError::Message(e)
66    }
67}
68
69impl<'a> From<&'a str> for AppError {
70    fn from(e: &str) -> Self {
71        AppError::Message(e.to_string())
72    }
73}
74
75impl From<Cow<'static, str>> for AppError {
76    fn from(e: Cow<'static, str>) -> Self {
77        AppError::Message(e.to_string())
78    }
79}
80
81impl From<io::Error> for AppError {
82    fn from(e: io::Error) -> Self {
83        AppError::Io(e)
84    }
85}
86
87impl From<glob::PatternError> for AppError {
88    fn from(e: glob::PatternError) -> Self {
89        AppError::Message(e.description().to_string())
90    }
91}
92
93impl From<std::num::ParseIntError> for AppError {
94    fn from(e: std::num::ParseIntError) -> Self {
95        AppError::Message(e.description().to_string())
96    }
97}
98
99
100pub fn build_dic(input_dir: &Path, output_dir: &Path, delimiter: String, encoding: &str) -> AppResult<i32> {
101    info!("output_dir: {}, input_dir: {}, delimiter: {:?}, encoding: {}",
102          output_dir.display(), input_dir.display(), delimiter, encoding);
103    fs::create_dir_all(&output_dir).expect("couldn't create directory");
104
105    let start_time = Instant::now();
106    let mut wd = WordDic::new(input_dir, encoding, output_dir, delimiter);
107    let cc = CharCategory::new(input_dir, encoding, output_dir);
108    println!("### Build word trie");
109    wd.build_word_id_map()?;
110
111    println!("### Build word dictionary");
112    wd.build_word_info()?;
113
114    println!("### Build matrix");
115    matrix::build(input_dir, output_dir)?;
116
117    println!("### Build char-category dictionary");
118    cc.build()?;
119
120    let elapsed = start_time.elapsed();
121    let ms = ((elapsed.as_secs() as f64) * 1000.0)
122        + ((elapsed.subsec_nanos() as f64) / 1_000_000.0);
123    println!("DONE");
124    println!("elapsed: {} ms", ms);
125    Ok(0)
126}