aion_package/codegen/
error.rs1use std::path::PathBuf;
4
5use crate::PackagingError;
6
7#[derive(thiserror::Error, Debug)]
15pub enum CodegenError {
16 #[error(transparent)]
20 Config(#[from] PackagingError),
21
22 #[error("gleam.toml package name `{name}` cannot name the generated module: {reason}")]
25 ProjectName {
26 name: String,
28 reason: String,
30 },
31
32 #[error(
36 "invalid workflow.toml: {field}: schema {path} is outside the schemas/ directory; \
37 `aion codegen` only generates from schemas/*.json"
38 )]
39 SchemaOutsideSchemasDir {
40 field: String,
42 path: PathBuf,
44 },
45
46 #[error("schemas directory {path} does not exist")]
48 SchemasDirMissing {
49 path: PathBuf,
51 },
52
53 #[error("no *.json schema files found in {path}")]
55 SchemasDirEmpty {
56 path: PathBuf,
58 },
59
60 #[error("failed to list schemas directory {path}: {source}")]
62 SchemasDirRead {
63 path: PathBuf,
65 source: std::io::Error,
67 },
68
69 #[error("failed to read schema {path}: {source}")]
71 SchemaRead {
72 path: PathBuf,
74 source: std::io::Error,
76 },
77
78 #[error("schema {path} is not valid JSON: {source}")]
81 SchemaParse {
82 path: PathBuf,
84 source: serde_json::Error,
86 },
87
88 #[error("schema file name {path} cannot name a Gleam type: {reason}")]
90 SchemaFileName {
91 path: PathBuf,
93 reason: String,
95 },
96
97 #[error("unsupported JSON Schema construct in {file} at `{pointer}`: {construct}")]
99 UnsupportedConstruct {
100 file: PathBuf,
102 pointer: String,
104 construct: String,
106 },
107
108 #[error(
110 "generated Gleam name `{name}` collides: derived from {first_file} at \
111 `{first_pointer}` and from {second_file} at `{second_pointer}`; \
112 rename one of the schema properties or files"
113 )]
114 NameCollision {
115 name: String,
117 first_file: PathBuf,
119 first_pointer: String,
121 second_file: PathBuf,
123 second_pointer: String,
125 },
126
127 #[error("failed to write generated module {path}: {source}")]
129 Write {
130 path: PathBuf,
132 source: std::io::Error,
134 },
135
136 #[error("--check failed: generated module {path} does not exist; run `aion codegen`")]
138 CheckMissing {
139 path: PathBuf,
141 },
142
143 #[error(
145 "--check failed: {path} differs from the schema-generated output; \
146 run `aion codegen` to regenerate it"
147 )]
148 CheckDrift {
149 path: PathBuf,
151 },
152
153 #[error("failed to read {path} for --check: {source}")]
155 CheckRead {
156 path: PathBuf,
158 source: std::io::Error,
160 },
161}
162
163#[cfg(test)]
164mod tests {
165 use std::path::PathBuf;
166
167 use super::CodegenError;
168
169 fn assert_send_sync<T: Send + Sync + 'static>() {}
170
171 #[test]
172 fn codegen_error_is_send_sync_and_static() {
173 assert_send_sync::<CodegenError>();
174 }
175
176 #[test]
177 fn display_messages_name_file_and_pointer() {
178 assert_eq!(
179 CodegenError::UnsupportedConstruct {
180 file: PathBuf::from("schemas/input.json"),
181 pointer: "/properties/tag/oneOf".to_owned(),
182 construct: "unrecognised keyword `oneOf`".to_owned(),
183 }
184 .to_string(),
185 "unsupported JSON Schema construct in schemas/input.json at \
186 `/properties/tag/oneOf`: unrecognised keyword `oneOf`"
187 );
188 assert_eq!(
189 CodegenError::CheckDrift {
190 path: PathBuf::from("src/demo_io.gleam"),
191 }
192 .to_string(),
193 "--check failed: src/demo_io.gleam differs from the schema-generated \
194 output; run `aion codegen` to regenerate it"
195 );
196 assert_eq!(
197 CodegenError::CheckMissing {
198 path: PathBuf::from("src/demo_io.gleam"),
199 }
200 .to_string(),
201 "--check failed: generated module src/demo_io.gleam does not exist; \
202 run `aion codegen`"
203 );
204 assert_eq!(
205 CodegenError::SchemaOutsideSchemasDir {
206 field: "workflow[0].input_schema".to_owned(),
207 path: PathBuf::from("/project/io/input.json"),
208 }
209 .to_string(),
210 "invalid workflow.toml: workflow[0].input_schema: schema \
211 /project/io/input.json is outside the schemas/ directory; \
212 `aion codegen` only generates from schemas/*.json"
213 );
214 }
215
216 #[test]
217 fn packaging_errors_convert_transparently() {
218 let error = CodegenError::from(crate::PackagingError::ConfigMissing {
219 root: PathBuf::from("/project"),
220 });
221
222 assert_eq!(error.to_string(), "no workflow.toml found in /project");
223 assert!(matches!(error, CodegenError::Config(_)));
224 }
225}