1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use std::fs::File;
use std::io::{BufRead, BufReader, Error as IOError, Seek};
use std::path::Path;

use thiserror::Error;

use super::dictionary_header::{DictionaryHeader, DictionaryHeaderErr};
use super::double_array_lexicon::DoubleArrayLexicon;
use super::grammar::Grammar;
use super::lexicon::LexiconErr;
use super::system_dictionary_version::{
  SYSTEM_DICT_VERSION, USER_DICT_VERSION_1, USER_DICT_VERSION_2,
};

#[derive(Error, Debug)]
pub enum ReadDictionaryErr {
  #[error("invalid dictionary version")]
  InvalidDictionaryVersionErr,
  #[error("invalid system dictionary")]
  InvalidSystemDictionaryErr,
  #[error("invalid user dictionary")]
  InvalidUserDictionaryErr,
  #[error("not found grammar")]
  NotFoundGrammarErr,
  #[error("{0}")]
  IOError(#[from] IOError),
  #[error("{0}")]
  DictionaryHeaderErr(#[from] DictionaryHeaderErr),
  #[error("{0}")]
  LexiconErr(#[from] LexiconErr),
}

pub struct BinaryDictionary {
  pub grammar: Grammar,
  header: DictionaryHeader,
  pub lexicon: DoubleArrayLexicon,
}

impl BinaryDictionary {
  fn new(
    grammar: Grammar,
    header: DictionaryHeader,
    lexicon: DoubleArrayLexicon,
  ) -> BinaryDictionary {
    BinaryDictionary {
      grammar,
      header,
      lexicon,
    }
  }
  pub fn read_dictionary_from_reader<R: Seek + BufRead>(
    reader: &mut R,
  ) -> Result<BinaryDictionary, ReadDictionaryErr> {
    let header = DictionaryHeader::from_reader(reader)?;

    if SYSTEM_DICT_VERSION != header.version
      && USER_DICT_VERSION_1 != header.version
      && USER_DICT_VERSION_2 != header.version
    {
      return Err(ReadDictionaryErr::InvalidDictionaryVersionErr);
    }
    if header.version == USER_DICT_VERSION_1 {
      return Err(ReadDictionaryErr::NotFoundGrammarErr);
    }
    let grammar = Grammar::from_reader(reader)?;

    let lexicon = DoubleArrayLexicon::from_reader(reader)?;
    Ok(BinaryDictionary::new(grammar, header, lexicon))
  }
  pub fn from_system_dictionary<P: AsRef<Path>>(
    filename: P,
  ) -> Result<BinaryDictionary, ReadDictionaryErr> {
    let mut reader = BufReader::new(File::open(filename)?);
    let dictionary = BinaryDictionary::read_dictionary_from_reader(&mut reader)?;
    if dictionary.header.version != SYSTEM_DICT_VERSION {
      return Err(ReadDictionaryErr::InvalidSystemDictionaryErr);
    }
    Ok(dictionary)
  }
  pub fn from_user_dictionary<P: AsRef<Path>>(
    filename: P,
  ) -> Result<BinaryDictionary, ReadDictionaryErr> {
    let mut reader = BufReader::new(File::open(filename)?);
    let dictionary = BinaryDictionary::read_dictionary_from_reader(&mut reader)?;
    if USER_DICT_VERSION_1 != dictionary.header.version
      && USER_DICT_VERSION_2 != dictionary.header.version
    {
      return Err(ReadDictionaryErr::InvalidUserDictionaryErr);
    }
    Ok(dictionary)
  }
}