use syn::{Ident, Type};
use crate::{util::Callable, Error, FromField, FromMeta};
use super::ParseAttribute;
#[derive(Debug, Clone)]
pub struct ForwardedField {
pub ident: Ident,
pub ty: Type,
pub with: Option<Callable>,
}
impl ForwardedField {
pub fn to_field_value(&self) -> syn::FieldValue {
let ident = &self.ident;
syn::FieldValue {
attrs: Vec::new(),
member: syn::Member::Named(ident.clone()),
colon_token: Some(Default::default()),
expr: syn::parse_quote!(#ident.expect("Errors were already checked")),
}
}
}
impl FromField for ForwardedField {
fn from_field(field: &syn::Field) -> crate::Result<Self> {
let result = Self {
ident: field.ident.clone().ok_or_else(|| {
Error::custom("forwarded field must be named field").with_span(field)
})?,
ty: field.ty.clone(),
with: None,
};
result.parse_attributes(&field.attrs)
}
}
impl ParseAttribute for ForwardedField {
fn parse_nested(&mut self, mi: &syn::Meta) -> crate::Result<()> {
if mi.path().is_ident("with") {
if self.with.is_some() {
return Err(Error::duplicate_field_path(mi.path()).with_span(mi));
}
self.with = FromMeta::from_meta(mi)?;
Ok(())
} else {
Err(Error::unknown_field_path_with_alts(mi.path(), &["with"]).with_span(mi))
}
}
}