obake_macros 1.0.4

Macros for versioned data-structures
Documentation
use syn::Token;

pub use proc_macro::TokenStream;
pub use proc_macro2::{Span, TokenStream as TokenStream2};

pub use semver::{Version, VersionReq};

#[derive(Clone)]
pub struct VersionAttr {
    pub version: Version,
    pub span: Span,
}

impl PartialEq for VersionAttr {
    fn eq(&self, other: &Self) -> bool {
        self.version == other.version
    }
}

impl Eq for VersionAttr {}

impl PartialOrd for VersionAttr {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        self.version.partial_cmp(&other.version)
    }
}

impl Ord for VersionAttr {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.version.cmp(&other.version)
    }
}

#[derive(Clone)]
pub struct CfgAttr {
    pub req: VersionReq,
    pub span: Span,
}

#[derive(Clone)]
pub struct InheritAttr {
    pub span: Span,
}

#[derive(Clone)]
pub struct DeriveAttr {
    pub span: Span,
    pub tokens: TokenStream2,
}

#[cfg(feature = "serde")]
#[derive(Clone)]
pub struct SerdeAttr {
    pub span: Span,
    pub tokens: TokenStream2,
}

#[derive(Clone)]
pub enum ObakeAttribute {
    Version(VersionAttr),
    Cfg(CfgAttr),
    Inherit(InheritAttr),
    Derive(DeriveAttr),
    #[cfg(feature = "serde")]
    Serde(SerdeAttr),
}

#[derive(Clone)]
pub struct VersionedField {
    pub attrs: VersionedAttributes,
    pub vis: syn::Visibility,
    pub ident: syn::Ident,
    pub colon_token: Token![:],
    pub ty: syn::Type,
}

#[derive(Clone)]
pub enum VersionedAttribute {
    Obake(ObakeAttribute),
    Attribute(syn::Attribute),
}

#[derive(Clone)]
pub struct VersionedAttributes {
    pub attrs: Vec<VersionedAttribute>,
}

impl ObakeAttribute {
    pub fn version(&self) -> Option<&VersionAttr> {
        #![allow(clippy::match_wildcard_for_single_variants)]
        match &self {
            ObakeAttribute::Version(version) => Some(version),
            _ => None,
        }
    }

    pub fn cfg(&self) -> Option<&CfgAttr> {
        #![allow(clippy::match_wildcard_for_single_variants)]
        match &self {
            ObakeAttribute::Cfg(cfg) => Some(cfg),
            _ => None,
        }
    }

    pub fn inherit(&self) -> Option<&InheritAttr> {
        #![allow(clippy::match_wildcard_for_single_variants)]
        match &self {
            ObakeAttribute::Inherit(inherit) => Some(inherit),
            _ => None,
        }
    }

    pub fn derive(&self) -> Option<&DeriveAttr> {
        #![allow(clippy::match_wildcard_for_single_variants)]
        match &self {
            ObakeAttribute::Derive(derive) => Some(derive),
            _ => None,
        }
    }

    #[cfg(feature = "serde")]
    pub fn serde(&self) -> Option<&SerdeAttr> {
        #![allow(clippy::match_wildcard_for_single_variants)]
        match &self {
            ObakeAttribute::Serde(serde) => Some(serde),
            _ => None,
        }
    }
}

impl VersionedAttribute {
    pub fn obake(&self) -> Option<&ObakeAttribute> {
        #![allow(clippy::match_wildcard_for_single_variants)]
        match &self {
            VersionedAttribute::Obake(obake) => Some(obake),
            _ => None,
        }
    }

    pub fn attr(&self) -> Option<&syn::Attribute> {
        #![allow(clippy::match_wildcard_for_single_variants)]
        match self {
            VersionedAttribute::Attribute(attr) => Some(attr),
            _ => None,
        }
    }
}

impl VersionedAttributes {
    pub fn obake(&self) -> impl Iterator<Item = &ObakeAttribute> + '_ {
        self.attrs.iter().filter_map(VersionedAttribute::obake)
    }

    pub fn versions(&self) -> impl Iterator<Item = &VersionAttr> + '_ {
        self.obake().filter_map(ObakeAttribute::version)
    }

    pub fn cfgs(&self) -> impl Iterator<Item = &CfgAttr> + '_ {
        self.obake().filter_map(ObakeAttribute::cfg)
    }

    pub fn inherits(&self) -> impl Iterator<Item = &InheritAttr> + '_ {
        self.obake().filter_map(ObakeAttribute::inherit)
    }

    pub fn derives(&self) -> impl Iterator<Item = &DeriveAttr> + '_ {
        self.obake().filter_map(ObakeAttribute::derive)
    }

    #[cfg(feature = "serde")]
    pub fn serdes(&self) -> impl Iterator<Item = &SerdeAttr> + '_ {
        self.obake().filter_map(ObakeAttribute::serde)
    }

    pub fn attrs(&self) -> impl Iterator<Item = &syn::Attribute> + '_ {
        self.attrs.iter().filter_map(VersionedAttribute::attr)
    }
}

#[derive(Clone)]
pub struct VersionedFields {
    pub brace_token: syn::token::Brace,
    pub fields: syn::punctuated::Punctuated<VersionedField, Token![,]>,
}

#[derive(Clone)]
pub enum VersionedVariantFields {
    Unnamed(syn::FieldsUnnamed),
    Named(VersionedFields),
    Unit,
}

#[derive(Clone)]
pub struct VersionedVariant {
    pub attrs: VersionedAttributes,
    pub ident: syn::Ident,
    pub fields: VersionedVariantFields,
}

#[derive(Clone)]
pub struct VersionedVariants {
    pub brace_token: syn::token::Brace,
    pub variants: syn::punctuated::Punctuated<VersionedVariant, Token![,]>,
}

#[derive(Clone)]
pub struct VersionedStruct {
    pub struct_token: Token![struct],
    pub ident: syn::Ident,
    pub fields: VersionedFields,
}

#[derive(Clone)]
pub struct VersionedEnum {
    pub enum_token: Token![enum],
    pub ident: syn::Ident,
    pub variants: VersionedVariants,
}

#[derive(Clone)]
pub enum VersionedItemKind {
    Struct(VersionedStruct),
    Enum(VersionedEnum),
}

#[derive(Clone)]
pub struct VersionedItem {
    pub attrs: VersionedAttributes,
    pub vis: syn::Visibility,
    pub kind: VersionedItemKind,
}

impl VersionedItem {
    pub fn ident(&self) -> &syn::Ident {
        match &self.kind {
            VersionedItemKind::Struct(inner) => &inner.ident,
            VersionedItemKind::Enum(inner) => &inner.ident,
        }
    }

    pub fn keyword_span(&self) -> Span {
        match &self.kind {
            VersionedItemKind::Struct(inner) => inner.struct_token.span,
            VersionedItemKind::Enum(inner) => inner.enum_token.span,
        }
    }
}