1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
extern crate proc_macro;
mod attribute_parser;
mod derive_enum;
mod derive_named_fields;
mod derive_struct;
mod derive_user_provided_function;
mod parse_type;
use attribute_parser::TagType;
use derive_named_fields::generate_named_fields_impl;
use parse_type::{DerivedTypeInfo, TraitImplementationInfo, VariantData};
use proc_macro::TokenStream;
use proc_macro2::Span;
use syn::{parse_macro_input, DeriveInput};
#[proc_macro_derive(Deserr, attributes(deserr, serde))]
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
match DerivedTypeInfo::parse(input) {
Ok(derived_type_info) => match derived_type_info.data {
TraitImplementationInfo::Struct(fields) => {
derive_struct::generate_derive_struct_impl(derived_type_info.common, fields).into()
}
TraitImplementationInfo::Enum { tag, variants } => match tag {
TagType::Internal(tag_key) => derive_enum::generate_derive_tagged_enum_impl(
derived_type_info.common,
tag_key,
variants,
)
.into(),
TagType::External
if variants
.iter()
.all(|variant| matches!(variant.data, VariantData::Unit)) =>
{
derive_enum::generate_derive_untagged_enum_impl(
derived_type_info.common,
variants,
)
.into()
}
TagType::External =>
syn::Error::new(
Span::call_site(),
r##"Externally tagged enums are not supported yet by deserr. Add #[deserr(tag = "some_tag_key")]"##,
).to_compile_error().into()
},
TraitImplementationInfo::UnfallibleUserProvidedFunction { from_attr } => {
derive_user_provided_function::generate_derive_from_user_function(
derived_type_info.common,
from_attr,
)
.into()
}
TraitImplementationInfo::FallibleUserProvidedFunction { try_from_attr } => {
derive_user_provided_function::generate_derive_try_from_user_function(
derived_type_info.common,
try_from_attr,
)
.into()
}
},
Err(e) => e.to_compile_error().into(),
}
}