conjure_codegen/
errors.rs1use proc_macro2::TokenStream;
15use quote::quote;
16
17use crate::context::{BaseModule, Context};
18use crate::objects;
19use crate::types::objects::{ErrorDefinition, ObjectDefinition};
20
21pub fn error_object_definition(def: &ErrorDefinition) -> ObjectDefinition {
22 ObjectDefinition::builder()
23 .type_name(def.error_name().clone())
24 .fields(def.safe_args().iter().chain(def.unsafe_args()).cloned())
25 .docs(def.docs().cloned())
26 .build()
27}
28
29pub fn generate(ctx: &Context, def: &ErrorDefinition) -> TokenStream {
30 let object = error_object_definition(def);
31 let object_def = objects::generate(ctx, BaseModule::Errors, &object);
32 let error_type = generate_error_type(ctx, def);
33
34 quote! {
35 #object_def
36 #error_type
37 }
38}
39
40fn generate_error_type(ctx: &Context, def: &ErrorDefinition) -> TokenStream {
41 let type_name = ctx.type_name(def.error_name().name());
42 let code = ctx.type_name(def.code().as_str());
43 let name = format!("{}:{}", def.namespace(), def.error_name().name());
44
45 let mut safe_args = def
46 .safe_args()
47 .iter()
48 .map(|f| &f.field_name().0)
49 .collect::<Vec<_>>();
50 safe_args.sort();
51
52 quote! {
53 impl conjure_error::ErrorType for #type_name {
54 #[inline]
55 fn code() -> conjure_error::ErrorCode {
56 conjure_error::ErrorCode::#code
57 }
58
59 #[inline]
60 fn name() -> &'static str {
61 #name
62 }
63
64 #[inline]
65 fn safe_args() -> &'static [&'static str] {
66 &[#(#safe_args,)*]
67 }
68 }
69 }
70}