1use std::{error::Error as StdError, fmt};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum CodegenError {
6 OptionalFieldUnsupported { container: String, field: String },
8 DefaultValueUnsupported { container: String, field: String },
10 EnumFieldUnsupported {
12 container: String,
13 field: String,
14 ty: String,
15 },
16 EnumRepresentationUnsupported { enum_name: String, repr: String },
18 EnumVariantValueRequired { enum_name: String, variant: String },
20 EnumVariantValueOutOfRange {
22 enum_name: String,
23 variant: String,
24 value: i64,
25 repr: String,
26 },
27 UnboundedStringUnsupported { container: String, field: String },
29 LegacyMessageUnsupported { packet: String },
31 MissingMid { packet: String },
33 MessageIdUnsupported { item: String },
35 MessageIdValueUnsupported { packet: String },
37 MissingCommandCode { packet: String },
39 CommandCodeUnsupported { item: String },
41 CommandCodeValueUnsupported { packet: String },
43 DuplicateMid {
45 mid: String,
46 first_packet: String,
47 second_packet: String,
48 },
49 DuplicateCommandCode {
51 mid: String,
52 cc: String,
53 first_packet: String,
54 second_packet: String,
55 },
56 MidRangeMismatch {
58 packet: String,
59 mid: String,
60 expected: &'static str,
61 },
62 DynamicArrayUnsupported {
64 container: String,
65 field: String,
66 ty: String,
67 },
68 BoundedArrayUnsupported {
70 container: String,
71 field: String,
72 ty: String,
73 },
74}
75
76impl fmt::Display for CodegenError {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 match self {
79 CodegenError::OptionalFieldUnsupported { .. }
80 | CodegenError::DefaultValueUnsupported { .. }
81 | CodegenError::UnboundedStringUnsupported { .. }
82 | CodegenError::DynamicArrayUnsupported { .. }
83 | CodegenError::BoundedArrayUnsupported { .. } => fmt_field_error(self, f),
84 CodegenError::EnumFieldUnsupported { .. }
85 | CodegenError::EnumRepresentationUnsupported { .. }
86 | CodegenError::EnumVariantValueRequired { .. }
87 | CodegenError::EnumVariantValueOutOfRange { .. } => fmt_enum_error(self, f),
88 CodegenError::LegacyMessageUnsupported { .. }
89 | CodegenError::MissingMid { .. }
90 | CodegenError::MessageIdUnsupported { .. }
91 | CodegenError::MessageIdValueUnsupported { .. }
92 | CodegenError::MidRangeMismatch { .. } => fmt_mid_error(self, f),
93 CodegenError::MissingCommandCode { .. }
94 | CodegenError::CommandCodeUnsupported { .. }
95 | CodegenError::CommandCodeValueUnsupported { .. } => fmt_command_error(self, f),
96 CodegenError::DuplicateMid { .. } | CodegenError::DuplicateCommandCode { .. } => {
97 fmt_duplicate_error(self, f)
98 }
99 }
100 }
101}
102
103fn fmt_field_error(error: &CodegenError, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 match error {
105 CodegenError::OptionalFieldUnsupported { .. }
106 | CodegenError::DefaultValueUnsupported { .. }
107 | CodegenError::UnboundedStringUnsupported { .. } => fmt_scalar_field_error(error, f),
108 CodegenError::DynamicArrayUnsupported { .. }
109 | CodegenError::BoundedArrayUnsupported { .. } => fmt_array_field_error(error, f),
110 _ => unreachable!("non-field error passed to fmt_field_error"),
111 }
112}
113
114fn fmt_scalar_field_error(error: &CodegenError, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 match error {
116 CodegenError::OptionalFieldUnsupported { container, field } => write!(
117 f,
118 "optional field `{container}.{field}` is not supported by cFS codegen yet"
119 ),
120 CodegenError::DefaultValueUnsupported { container, field } => write!(
121 f,
122 "default value for field `{container}.{field}` is not supported by cFS codegen yet"
123 ),
124 CodegenError::UnboundedStringUnsupported { container, field } => write!(
125 f,
126 "unbounded string field `{container}.{field}` is not supported by cFS codegen; use `string[<=N]` or `string[N]`"
127 ),
128 _ => unreachable!("non-scalar field error passed to fmt_scalar_field_error"),
129 }
130}
131
132fn fmt_array_field_error(error: &CodegenError, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133 match error {
134 CodegenError::DynamicArrayUnsupported {
135 container,
136 field,
137 ty,
138 } => write!(
139 f,
140 "dynamic array field `{container}.{field}` with type `{ty}` is not supported by cFS codegen yet"
141 ),
142 CodegenError::BoundedArrayUnsupported {
143 container,
144 field,
145 ty,
146 } => write!(
147 f,
148 "bounded array field `{container}.{field}` with type `{ty}` is not supported by cFS codegen yet"
149 ),
150 _ => unreachable!("non-array field error passed to fmt_array_field_error"),
151 }
152}
153
154fn fmt_enum_error(error: &CodegenError, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155 match error {
156 CodegenError::EnumFieldUnsupported {
157 container,
158 field,
159 ty,
160 } => write!(
161 f,
162 "enum field `{container}.{field}` with type `{ty}` needs an explicit integer representation for cFS codegen"
163 ),
164 CodegenError::EnumRepresentationUnsupported { enum_name, repr } => write!(
165 f,
166 "enum `{enum_name}` uses unsupported representation `{repr}`; cFS codegen supports integer enum representations"
167 ),
168 CodegenError::EnumVariantValueRequired { enum_name, variant } => write!(
169 f,
170 "enum `{enum_name}` variant `{variant}` needs an explicit value for cFS codegen"
171 ),
172 CodegenError::EnumVariantValueOutOfRange {
173 enum_name,
174 variant,
175 value,
176 repr,
177 } => write!(
178 f,
179 "enum `{enum_name}` variant `{variant}` value `{value}` does not fit `{repr}`"
180 ),
181 _ => unreachable!("non-enum error passed to fmt_enum_error"),
182 }
183}
184
185fn fmt_mid_error(error: &CodegenError, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186 match error {
187 CodegenError::LegacyMessageUnsupported { .. }
188 | CodegenError::MissingMid { .. }
189 | CodegenError::MessageIdUnsupported { .. } => fmt_mid_presence_error(error, f),
190 CodegenError::MessageIdValueUnsupported { .. } | CodegenError::MidRangeMismatch { .. } => {
191 fmt_mid_value_error(error, f)
192 }
193 _ => unreachable!("non-MID error passed to fmt_mid_error"),
194 }
195}
196
197fn fmt_mid_presence_error(error: &CodegenError, f: &mut fmt::Formatter<'_>) -> fmt::Result {
198 match error {
199 CodegenError::LegacyMessageUnsupported { packet } => write!(
200 f,
201 "legacy message `{packet}` is not supported by cFS codegen; use `command` or `telemetry`"
202 ),
203 CodegenError::MissingMid { packet } => {
204 write!(f, "packet `{packet}` is missing required `@mid(...)`")
205 }
206 CodegenError::MessageIdUnsupported { item } => write!(
207 f,
208 "`@mid(...)` is only supported on command and telemetry packets, found on `{item}`"
209 ),
210 _ => unreachable!("non-MID presence error passed to fmt_mid_presence_error"),
211 }
212}
213
214fn fmt_mid_value_error(error: &CodegenError, f: &mut fmt::Formatter<'_>) -> fmt::Result {
215 match error {
216 CodegenError::MessageIdValueUnsupported { packet } => write!(
217 f,
218 "packet `{packet}` has unresolved or non-integer `@mid(...)`; cFS codegen requires an integer, hex, local integer constant, or imported integer constant message ID"
219 ),
220 CodegenError::MidRangeMismatch {
221 packet,
222 mid,
223 expected,
224 } => write!(f, "packet `{packet}` has MID `{mid}`, expected {expected}"),
225 _ => unreachable!("non-MID value error passed to fmt_mid_value_error"),
226 }
227}
228
229fn fmt_command_error(error: &CodegenError, f: &mut fmt::Formatter<'_>) -> fmt::Result {
230 match error {
231 CodegenError::MissingCommandCode { packet } => {
232 write!(f, "command `{packet}` is missing required `@cc(...)`")
233 }
234 CodegenError::CommandCodeUnsupported { item } => write!(
235 f,
236 "`@cc(...)` is only supported on command packets, found on `{item}`"
237 ),
238 CodegenError::CommandCodeValueUnsupported { packet } => write!(
239 f,
240 "command `{packet}` has unresolved or non-integer `@cc(...)`; cFS codegen requires an integer, hex, or local integer constant command code"
241 ),
242 _ => unreachable!("non-command error passed to fmt_command_error"),
243 }
244}
245
246fn fmt_duplicate_error(error: &CodegenError, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247 match error {
248 CodegenError::DuplicateMid {
249 mid,
250 first_packet,
251 second_packet,
252 } => write!(
253 f,
254 "duplicate MID `{mid}` used by packets `{first_packet}` and `{second_packet}`"
255 ),
256 CodegenError::DuplicateCommandCode {
257 mid,
258 cc,
259 first_packet,
260 second_packet,
261 } => write!(
262 f,
263 "duplicate command MID/CC pair `{mid}`/`{cc}` used by packets `{first_packet}` and `{second_packet}`"
264 ),
265 _ => unreachable!("non-duplicate error passed to fmt_duplicate_error"),
266 }
267}
268
269impl StdError for CodegenError {}