use {
proc_macro2::TokenStream,
quote::ToTokens,
syn::{
Attribute,
Generics,
Ident,
Token,
TypeParamBound,
parse::ParseStream,
punctuated::Punctuated,
},
};
#[derive(Debug, Clone)]
pub struct AssociatedTypeBase {
pub attributes: Vec<Attribute>,
pub type_token: Token![type],
pub name: Ident,
pub generics: Generics,
pub colon_token: Option<Token![:]>,
pub output_bounds: Punctuated<TypeParamBound, Token![+]>,
}
impl ToTokens for AssociatedTypeBase {
fn to_tokens(
&self,
tokens: &mut TokenStream,
) {
for attr in &self.attributes {
attr.to_tokens(tokens);
}
self.type_token.to_tokens(tokens);
self.name.to_tokens(tokens);
self.generics.to_tokens(tokens);
if let Some(colon) = &self.colon_token {
colon.to_tokens(tokens);
self.output_bounds.to_tokens(tokens);
}
}
}
impl AssociatedTypeBase {
pub fn parse_signature(
input: ParseStream,
terminator_check: impl Fn(ParseStream) -> bool,
) -> syn::Result<Self> {
let attributes = input.call(Attribute::parse_outer)?;
let type_token: Token![type] = input.parse()?;
let name: Ident = input.parse()?;
let generics: Generics = input.parse()?;
let mut colon_token: Option<Token![:]> = None;
let mut output_bounds = Punctuated::new();
if input.peek(Token![:]) {
colon_token = Some(input.parse()?);
loop {
if terminator_check(input) {
break;
}
output_bounds.push_value(input.parse()?);
if input.peek(Token![+]) {
output_bounds.push_punct(input.parse()?);
} else {
break;
}
}
}
Ok(AssociatedTypeBase {
attributes,
type_token,
name,
generics,
colon_token,
output_bounds,
})
}
}