igo/dictionary/build/
mod.rs1use 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}