Skip to main content

conjure_codegen/
errors.rs

1// Copyright 2019 Palantir Technologies, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14use 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}