sudachi/dic/build/
error.rs1use crate::error::SudachiError;
18use crate::prelude::SudachiResult;
19use thiserror::Error;
20
21#[derive(Error, Debug)]
24#[error("{file}:{line}\t{cause}")]
25pub struct DicBuildError {
26 pub file: String,
27 pub line: usize,
28 pub cause: BuildFailure,
29}
30
31#[derive(Error, Debug)]
33#[non_exhaustive]
34pub enum BuildFailure {
35 #[error("The actual size {actual} was larger than expected {expected}")]
36 InvalidSize { actual: usize, expected: usize },
37
38 #[error("The actual size of {field} {actual} was larger than expected {expected}")]
39 InvalidFieldSize {
40 actual: usize,
41 expected: usize,
42 field: &'static str,
43 },
44
45 #[error(transparent)]
47 Io(#[from] std::io::Error),
48
49 #[error("Field {0} did not exist in CSV lexicon")]
50 NoRawField(&'static str),
51
52 #[error(transparent)]
53 CsvError(csv::Error),
54
55 #[error("Invalid character literal {0}")]
56 InvalidCharLiteral(String),
57
58 #[error("Invalid i16 literal {0}")]
59 InvalidI16Literal(String),
60
61 #[error("Invalid u32 literal {0}")]
62 InvalidU32Literal(String),
63
64 #[error("Invalid word id: {0}")]
65 InvalidWordId(String),
66
67 #[error("Invalid word split {0}")]
68 InvalidSplit(String),
69
70 #[error("Invalid word split format - field {field} did not exist in {original}")]
71 SplitFormatError {
72 field: &'static str,
73 original: String,
74 },
75
76 #[error("Surface can't be empty")]
77 EmptySurface,
78
79 #[error("Maximum number of POS (2^15-1) exceeded with {0}")]
80 PosLimitExceeded(String),
81
82 #[error("Split reference {0} was incorrect")]
83 InvalidSplitWordReference(String),
84
85 #[error("Lexicon contains unresolved splits, call resolve()")]
86 UnresolvedSplits,
87
88 #[error("Connection size {0} was invalid: {1}")]
89 InvalidConnSize(&'static str, i16),
90
91 #[error("WordId table is not built, call build_word_id_table()")]
92 WordIdTableNotBuilt,
93
94 #[error("Failed to build trie")]
95 TrieBuildFailure,
96}
97
98#[derive(Default)]
99pub(crate) struct DicCompilationCtx {
100 name: String,
101 line: usize,
102}
103
104impl DicCompilationCtx {
105 pub fn memory() -> Self {
106 DicCompilationCtx {
107 name: "<memory>".to_owned(),
108 line: 0,
109 }
110 }
111
112 #[inline]
113 pub fn err<T, E: Into<BuildFailure>>(&self, reason: E) -> SudachiResult<T> {
114 Err(self.to_sudachi_err(reason))
115 }
116
117 #[inline(always)]
118 pub fn to_sudachi_err<E: Into<BuildFailure>>(&self, reason: E) -> SudachiError {
119 match reason.into() {
120 BuildFailure::Io(e) => e.into(),
121 reason => {
122 let err = DicBuildError {
123 file: self.name.clone(),
124 line: self.line,
125 cause: reason,
126 };
127 err.into()
128 }
129 }
130 }
131
132 #[inline(never)]
133 #[cold]
134 pub fn to_sudachi_err_cold<E: Into<BuildFailure>>(&self, reason: E) -> SudachiError {
135 self.to_sudachi_err(reason)
136 }
137
138 #[inline(always)]
139 pub fn transform<T>(&self, result: DicWriteResult<T>) -> SudachiResult<T> {
140 match result {
141 Ok(v) => Ok(v),
142 Err(e) => Err(self.to_sudachi_err_cold(e)),
143 }
144 }
145
146 #[inline(always)]
147 pub fn apply<T, F: FnOnce() -> DicWriteResult<T>>(&self, f: F) -> SudachiResult<T> {
148 match f() {
149 Ok(v) => Ok(v),
150 Err(e) => Err(self.to_sudachi_err_cold(e)),
151 }
152 }
153
154 pub fn set_filename(&mut self, new_name: String) -> String {
155 std::mem::replace(&mut self.name, new_name)
156 }
157
158 pub fn add_line(&mut self, offset: usize) {
159 self.line += offset;
160 }
161
162 pub fn set_line(&mut self, line: usize) -> usize {
163 std::mem::replace(&mut self.line, line)
164 }
165}
166
167pub type DicWriteResult<T> = std::result::Result<T, BuildFailure>;