//! A Serde ast, parsed from the Syn ast and ready to generate Rust code.
usecrate::internals::{attr, check, Ctxt, Derive}; use syn::punctuated::Punctuated; use syn::Token;
/// A source data structure annotated with `#[derive(Serialize)]` and/or `#[derive(Deserialize)]`, /// parsed into an internal representation. pubstruct Container<'a> { /// The struct or enum name (without generics). pub ident: syn::Ident, /// Attributes on the structure, parsed for Serde. pub attrs: attr::Container, /// The contents of the struct or enum. pub data: Data<'a>, /// Any generics on the struct or enum. pub generics: &'a syn::Generics, /// Original input. pub original: &'a syn::DeriveInput,
}
/// The fields of a struct or enum. /// /// Analogous to `syn::Data`. pubenum Data<'a> { Enum(Vec<Variant<'a>>), Struct(Style, Vec<Field<'a>>),
}
/// A variant of an enum. pubstruct Variant<'a> { pub ident: syn::Ident, pub attrs: attr::Variant, pub style: Style, pub fields: Vec<Field<'a>>, pub original: &'a syn::Variant,
}
/// A field of a struct. pubstruct Field<'a> { pub member: syn::Member, pub attrs: attr::Field, pub ty: &'a syn::Type, pub original: &'a syn::Field,
}
#[derive(Copy, Clone)] pubenum Style { /// Named fields. Struct, /// Many unnamed fields.
Tuple, /// One unnamed field.
Newtype, /// No fields.
Unit,
}
impl<'a> Container<'a> { /// Convert the raw Syn ast into a parsed container object, collecting errors in `cx`. pubfn from_ast(
cx: &Ctxt,
item: &'a syn::DeriveInput,
derive: Derive,
) -> Option<Container<'a>> { let attrs = attr::Container::from_ast(cx, item);
letmut data = match &item.data {
syn::Data::Enum(data) => Data::Enum(enum_from_ast(cx, &data.variants, attrs.default())),
syn::Data::Struct(data) => { let (style, fields) = struct_from_ast(cx, &data.fields, None, attrs.default());
Data::Struct(style, fields)
}
syn::Data::Union(_) => {
cx.error_spanned_by(item, "Serde does not support derive for unions"); return None;
}
};
match &mut data {
Data::Enum(variants) => { for variant in variants {
variant.attrs.rename_by_rules(attrs.rename_all_rules()); for field in &mut variant.fields {
field.attrs.rename_by_rules(
variant
.attrs
.rename_all_rules()
.or(attrs.rename_all_fields_rules()),
);
}
}
}
Data::Struct(_, fields) => { for field in fields {
field.attrs.rename_by_rules(attrs.rename_all_rules());
}
}
}
let index_of_last_tagged_variant = variants
.iter()
.rposition(|variant| !variant.attrs.untagged()); iflet Some(index_of_last_tagged_variant) = index_of_last_tagged_variant { for variant in &variants[..index_of_last_tagged_variant] { if variant.attrs.untagged() {
cx.error_spanned_by(&variant.ident, "all variants with the #[serde(untagged)] attribute must be placed at the end of the enum");
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.