Skip to main content

apache_avro_derive/enums/
mod.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18mod plain;
19
20use crate::attributes::NamedTypeOptions;
21use proc_macro2::{Ident, Span, TokenStream};
22use syn::{Attribute, DataEnum, Fields, Meta};
23
24/// Generate a schema definition for a enum.
25pub fn get_data_enum_schema_def(
26    container_attrs: &NamedTypeOptions,
27    data_enum: &DataEnum,
28    ident_span: Span,
29) -> Result<TokenStream, Vec<syn::Error>> {
30    if data_enum.variants.iter().all(|v| Fields::Unit == v.fields) {
31        plain::schema_def(container_attrs, data_enum, ident_span)
32    } else {
33        Err(vec![syn::Error::new(
34            ident_span,
35            "AvroSchema: derive does not work for enums with non unit structs",
36        )])
37    }
38}
39
40fn default_enum_variant(
41    data_enum: &DataEnum,
42    error_span: Span,
43) -> Result<Option<String>, Vec<syn::Error>> {
44    match data_enum
45        .variants
46        .iter()
47        .filter(|v| v.attrs.iter().any(is_default_attr))
48        .collect::<Vec<_>>()
49    {
50        variants if variants.is_empty() => Ok(None),
51        single if single.len() == 1 => Ok(Some(single[0].ident.to_string())),
52        multiple => Err(vec![syn::Error::new(
53            error_span,
54            format!(
55                "Multiple defaults defined: {:?}",
56                multiple
57                    .iter()
58                    .map(|v| v.ident.to_string())
59                    .collect::<Vec<String>>()
60            ),
61        )]),
62    }
63}
64
65fn is_default_attr(attr: &Attribute) -> bool {
66    matches!(attr, Attribute { meta: Meta::Path(path), .. } if path.get_ident().map(Ident::to_string).as_deref() == Some("default"))
67}