schemars_derive/ast/
mod.rs

1mod from_serde;
2
3use crate::attr::{Attrs, ValidationAttrs};
4use from_serde::FromSerde;
5use serde_derive_internals::ast as serde_ast;
6use serde_derive_internals::{Ctxt, Derive};
7
8pub struct Container<'a> {
9    pub ident: syn::Ident,
10    pub serde_attrs: serde_derive_internals::attr::Container,
11    pub data: Data<'a>,
12    pub generics: syn::Generics,
13    pub original: &'a syn::DeriveInput,
14    pub attrs: Attrs,
15}
16
17pub enum Data<'a> {
18    Enum(Vec<Variant<'a>>),
19    Struct(serde_ast::Style, Vec<Field<'a>>),
20}
21
22pub struct Variant<'a> {
23    pub ident: syn::Ident,
24    pub serde_attrs: serde_derive_internals::attr::Variant,
25    pub style: serde_ast::Style,
26    pub fields: Vec<Field<'a>>,
27    pub original: &'a syn::Variant,
28    pub attrs: Attrs,
29}
30
31pub struct Field<'a> {
32    pub member: syn::Member,
33    pub serde_attrs: serde_derive_internals::attr::Field,
34    pub ty: &'a syn::Type,
35    pub original: &'a syn::Field,
36    pub attrs: Attrs,
37    pub validation_attrs: ValidationAttrs,
38}
39
40impl<'a> Container<'a> {
41    pub fn from_ast(item: &'a syn::DeriveInput) -> syn::Result<Container<'a>> {
42        let ctxt = Ctxt::new();
43        let result = serde_ast::Container::from_ast(&ctxt, item, Derive::Deserialize)
44            .ok_or(())
45            .and_then(|serde| Self::from_serde(&ctxt, serde));
46
47        ctxt.check()
48            .map(|_| result.expect("from_ast set no errors on Ctxt, so should have returned Ok"))
49    }
50
51    pub fn name(&self) -> &str {
52        self.serde_attrs.name().deserialize_name()
53    }
54
55    pub fn transparent_field(&'a self) -> Option<&'a Field> {
56        if self.serde_attrs.transparent() {
57            if let Data::Struct(_, fields) = &self.data {
58                return Some(&fields[0]);
59            }
60        }
61
62        None
63    }
64}
65
66impl<'a> Variant<'a> {
67    pub fn name(&self) -> &str {
68        self.serde_attrs.name().deserialize_name()
69    }
70
71    pub fn is_unit(&self) -> bool {
72        matches!(self.style, serde_ast::Style::Unit)
73    }
74}
75
76impl<'a> Field<'a> {
77    pub fn name(&self) -> &str {
78        self.serde_attrs.name().deserialize_name()
79    }
80}