1use std::fmt::{Display, Formatter};
4
5#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
7pub struct ParseError {
8 pub column: usize,
10 pub line: usize,
12 pub reason: DbdErrorReason,
14}
15
16impl ParseError {
17 pub(crate) const fn new(column: usize, line: usize, reason: DbdErrorReason) -> Self {
18 Self {
19 column,
20 line,
21 reason,
22 }
23 }
24
25 pub fn start_str_at<'a>(&self, mut contents: &'a str) -> Option<&'a str> {
27 let mut i = 0_usize;
28
29 if self.line == 0 {
30 return Some(&contents[self.column..]);
31 }
32
33 while let Some((_, b)) = contents.split_once('\n') {
34 i += 1;
35
36 if self.line == i {
37 return Some(&b[self.column..]);
38 }
39
40 contents = b;
41 }
42
43 None
44 }
45}
46
47impl Display for ParseError {
48 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
49 f.write_fmt(format_args!(
50 "Column {}, line {}: {}",
51 self.column, self.line, self.reason,
52 ))
53 }
54}
55
56impl std::error::Error for ParseError {}
57
58#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
60pub enum DbdErrorReason {
61 NoSpaceInColumn,
63
64 NoDoubleColonInForeignKey,
66 NoClosingForeignKeyAngleBracket,
68
69 NoClosingAnnotationDollarSign,
71
72 NoClosingIntegerSizeAngleBracket,
74 InvalidIntegerSizeNumber(String),
76
77 NoClosingArraySizeSquareBracket,
79 InvalidArraySizeNumber(String),
81
82 InvalidLayout(String),
84 InvalidBuild(String),
86
87 InvalidType(String),
89}
90
91impl Display for DbdErrorReason {
92 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
93 let s = match self {
94 DbdErrorReason::NoSpaceInColumn => "no space to separate column name and type",
95 DbdErrorReason::NoDoubleColonInForeignKey => {
96 "no '::' inside foreign key '<' and '>' brackets"
97 }
98 DbdErrorReason::NoClosingForeignKeyAngleBracket => {
99 "no matching '>' for opening '<' in foreign key"
100 }
101 DbdErrorReason::NoClosingAnnotationDollarSign => {
102 "no matching '$' for opening '$' in annotations"
103 }
104 DbdErrorReason::NoClosingArraySizeSquareBracket => {
105 "no matching ']' for opening '[' in array"
106 }
107 DbdErrorReason::NoClosingIntegerSizeAngleBracket => {
108 "no matching '>' for opening '<' in integer size"
109 }
110 DbdErrorReason::InvalidLayout(s) => {
111 return f.write_fmt(format_args!("invalid hex string for layout: '{}'", s));
112 }
113 DbdErrorReason::InvalidIntegerSizeNumber(s) => {
114 return f.write_fmt(format_args!("invalid integer size: '{}'", s));
115 }
116 DbdErrorReason::InvalidArraySizeNumber(s) => {
117 return f.write_fmt(format_args!("invalid array size: '{}'", s));
118 }
119 DbdErrorReason::InvalidType(s) => {
120 return f.write_fmt(format_args!("invalid type name: '{}'", s));
121 }
122 DbdErrorReason::InvalidBuild(s) => {
123 return f.write_fmt(format_args!("invalid build format: '{}'", s));
124 }
125 };
126 f.write_str(s)
127 }
128}
129
130#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
132pub enum ConversionError {
133 InvalidIntegerWidth(usize),
135 NoIntegerWidth,
137
138 ColumnNotFound(String),
140
141 LocStringAsForeignKey,
143 StringAsForeignKey,
145 FloatAsForeignKey,
147}
148
149impl Display for ConversionError {
150 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
151 match self {
152 ConversionError::InvalidIntegerWidth(i) => {
153 write!(f, "invalid integer size '{}'", i)
154 }
155 ConversionError::NoIntegerWidth => write!(f, "no integer width for integer"),
156 ConversionError::ColumnNotFound(s) => write!(f, "column not found '{}'", s),
157 ConversionError::LocStringAsForeignKey => {
158 write!(f, "LocString type is set as foreign key")
159 }
160 ConversionError::StringAsForeignKey => {
161 write!(f, "String type is set as foreign key")
162 }
163 ConversionError::FloatAsForeignKey => {
164 write!(f, "Float type is set as foreign key")
165 }
166 }
167 }
168}
169
170impl std::error::Error for ConversionError {}