185 lines
5.1 KiB
Rust
185 lines
5.1 KiB
Rust
use super::*;
|
|
|
|
ast_struct! {
|
|
/// An enum variant.
|
|
pub struct Variant {
|
|
/// Attributes tagged on the variant.
|
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
|
pub(crate) attrs: Vec<Attribute>,
|
|
|
|
/// Name of the variant.
|
|
pub(crate) ident: Ident,
|
|
|
|
/// Content stored in the variant.
|
|
pub(crate) fields: Fields,
|
|
|
|
/// Explicit discriminant: `Variant = 1`
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub(crate) discriminant: Option<Expr>,
|
|
}
|
|
}
|
|
|
|
ast_enum! {
|
|
/// Data stored within an enum variant or struct.
|
|
pub enum Fields {
|
|
/// Named fields of a struct or struct variant such as `Point { x: f64,
|
|
/// y: f64 }`.
|
|
Named(FieldsNamed),
|
|
|
|
/// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
|
|
Unnamed(FieldsUnnamed),
|
|
|
|
/// Unit struct or unit variant such as `None`.
|
|
Unit,
|
|
}
|
|
}
|
|
|
|
ast_struct! {
|
|
/// Named fields of a struct or struct variant such as `Point { x: f64,
|
|
/// y: f64 }`.
|
|
#[serde(transparent)]
|
|
pub struct FieldsNamed {
|
|
pub(crate) named: Punctuated<Field>,
|
|
}
|
|
}
|
|
|
|
ast_struct! {
|
|
/// Unnamed fields of a tuple struct or tuple variant such as `Some(T)`.
|
|
#[serde(transparent)]
|
|
pub struct FieldsUnnamed {
|
|
pub(crate) unnamed: Punctuated<Field>,
|
|
}
|
|
}
|
|
|
|
impl Fields {
|
|
pub(crate) fn is_named(&self) -> bool {
|
|
match self {
|
|
Fields::Named(_) => true,
|
|
Fields::Unnamed(_) | Fields::Unit => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
// assertions
|
|
// `syn::perse*` functions will detect these, but there is a possibility to
|
|
// generate incorrect code by subsequent operations.
|
|
pub(crate) fn assert_struct_semi(fields: &Fields, semi_token: bool) {
|
|
match fields {
|
|
// struct foo {};
|
|
Fields::Named(_) => assert!(!semi_token, "unexpected token: `;`"),
|
|
// struct foo ()
|
|
Fields::Unnamed(_) => assert!(
|
|
semi_token,
|
|
"unexpected end of input, expected `where` or `;`"
|
|
),
|
|
// struct foo
|
|
Fields::Unit => assert!(
|
|
semi_token,
|
|
"unexpected end of input, expected one of: `where`, parentheses, curly braces, `;`"
|
|
),
|
|
}
|
|
}
|
|
|
|
ast_struct! {
|
|
/// A field of a struct or enum variant.
|
|
pub struct Field {
|
|
/// Attributes tagged on the field.
|
|
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
|
pub(crate) attrs: Vec<Attribute>,
|
|
|
|
/// Visibility of the field.
|
|
#[serde(default, skip_serializing_if = "Visibility::is_inherited")]
|
|
pub(crate) vis: Visibility,
|
|
|
|
/// Name of the field, if any.
|
|
///
|
|
/// Fields of tuple structs have no names.
|
|
#[serde(default, skip_serializing_if = "Option::is_none")]
|
|
pub(crate) ident: Option<Ident>,
|
|
|
|
#[serde(default, skip_serializing_if = "not")]
|
|
pub(crate) colon_token: bool,
|
|
|
|
/// Type of the field.
|
|
pub(crate) ty: Type,
|
|
}
|
|
}
|
|
|
|
ast_enum! {
|
|
/// The visibility level of an item: inherited or `pub` or
|
|
/// `pub(restricted)`.
|
|
pub enum Visibility {
|
|
/// A public visibility level: `pub`.
|
|
#[serde(rename = "pub")]
|
|
Public,
|
|
|
|
/// A crate-level visibility: `crate`.
|
|
Crate,
|
|
|
|
/// A visibility level restricted to some path: `pub(self)` or
|
|
/// `pub(super)` or `pub(crate)` or `pub(in some::module)`.
|
|
Restricted(VisRestricted),
|
|
|
|
/// An inherited visibility, which usually means private.
|
|
Inherited,
|
|
}
|
|
}
|
|
|
|
impl Visibility {
|
|
pub(crate) fn is_inherited(&self) -> bool {
|
|
match self {
|
|
Visibility::Inherited => true,
|
|
_ => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for Visibility {
|
|
fn default() -> Self {
|
|
Visibility::Inherited
|
|
}
|
|
}
|
|
|
|
ast_struct! {
|
|
/// A visibility level restricted to some path: `pub(self)` or
|
|
/// `pub(super)` or `pub(crate)` or `pub(in some::module)`.
|
|
pub struct VisRestricted {
|
|
#[serde(default, skip_serializing_if = "not")]
|
|
pub(crate) in_token: bool,
|
|
pub(crate) path: Box<Path>,
|
|
}
|
|
}
|
|
|
|
mod convert {
|
|
use super::*;
|
|
|
|
// Visibility
|
|
syn_trait_impl!(syn::Visibility);
|
|
impl From<&syn::Visibility> for Visibility {
|
|
fn from(other: &syn::Visibility) -> Self {
|
|
use super::Visibility::*;
|
|
use syn::Visibility;
|
|
match other {
|
|
Visibility::Public(_) => Public,
|
|
Visibility::Crate(_) => Crate,
|
|
Visibility::Restricted(x) => Restricted(x.ref_into()),
|
|
Visibility::Inherited => Inherited,
|
|
}
|
|
}
|
|
}
|
|
impl From<&Visibility> for syn::Visibility {
|
|
fn from(other: &Visibility) -> Self {
|
|
use syn::Visibility::*;
|
|
match other {
|
|
Visibility::Public => Public(syn::VisPublic {
|
|
pub_token: default(),
|
|
}),
|
|
Visibility::Crate => Crate(syn::VisCrate {
|
|
crate_token: default(),
|
|
}),
|
|
Visibility::Restricted(x) => Restricted(x.into()),
|
|
Visibility::Inherited => Inherited,
|
|
}
|
|
}
|
|
}
|
|
}
|