Skip to content

Commit

Permalink
Added a way to relatively simply add custom attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorKoenders committed Dec 4, 2021
1 parent 4fe3a5b commit 0cedf89
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub use self::error::Error;
/// Useful includes
pub mod prelude {
pub use crate::generate::FnSelfArg;
pub use crate::parse::{Body, Parse};
pub use crate::parse::{Body, FromAttribute, Parse};
pub use crate::Result;
pub use proc_macro2::*;
}
Expand All @@ -90,7 +90,7 @@ pub mod prelude {
extern crate proc_macro;

pub use crate::generate::FnSelfArg;
pub use crate::parse::{Body, Parse};
pub use crate::parse::{Body, FromAttribute, Parse};
pub use crate::Result;
pub use proc_macro::*;
}
Expand Down
9 changes: 9 additions & 0 deletions src/parse/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,12 @@ fn test_attributes_try_take() {
x => panic!("Expected ident, found {:?}", x),
}
}

/// Helper trait for functions like:
/// - [`IdentOrIndex::has_field_attribute`]
///
/// This can be implemented on your own type to make parsing easier.
pub trait FromAttribute: Sized {
/// Try to parse the given group into your own type. Return `None` if the parsing failed or if the attribute was not this type.
fn parse(group: &Group) -> Option<Self>;
}
17 changes: 16 additions & 1 deletion src/parse/body.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::attributes::AttributeLocation;
use super::{utils::*, Attribute, Visibility};
use super::{utils::*, Attribute, FromAttribute, Visibility};
use crate::prelude::{Delimiter, Ident, Literal, Span, TokenTree};
use crate::{Error, Result};
use std::iter::Peekable;
Expand Down Expand Up @@ -507,6 +507,21 @@ impl<'a> IdentOrIndex<'a> {
}
}
}

pub fn has_field_attribute<T: FromAttribute + PartialEq<T>>(&self, attrib: T) -> bool {
let attributes = match self {
Self::Ident { attributes, .. } => attributes,
Self::Index { attributes, .. } => attributes,
};
for attribute in attributes.iter() {
if let Some(attribute) = T::parse(&attribute.tokens) {
if attribute == attrib {
return true;
}
}
}
false
}
}

impl std::fmt::Display for IdentOrIndex<'_> {
Expand Down
2 changes: 1 addition & 1 deletion src/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ mod generics;
mod utils;
mod visibility;

pub use self::attributes::{Attribute, AttributeLocation};
pub use self::attributes::{Attribute, AttributeLocation, FromAttribute};
pub use self::body::{EnumBody, EnumVariant, Fields, StructBody, UnnamedField};
pub(crate) use self::data_type::DataType;
pub use self::generics::{Generic, GenericConstraints, Generics, Lifetime, SimpleGeneric};
Expand Down

0 comments on commit 0cedf89

Please sign in to comment.