use quote::Tokens;
use syn::{Generics, Ident, Path, WherePredicate};
use codegen::{DefaultExpression, Field, Variant, FieldsGen};
use codegen::field;
use codegen::error::{ErrorCheck, ErrorDeclaration};
use ast::Data;
#[derive(Debug)]
pub struct TraitImpl<'a> {
pub ident: &'a Ident,
pub generics: &'a Generics,
pub data: Data<Variant<'a>, Field<'a>>,
pub default: Option<DefaultExpression<'a>>,
pub map: Option<&'a Path>,
pub bound: Option<&'a [WherePredicate]>,
}
impl<'a> TraitImpl<'a> {
pub fn declare_errors(&self) -> ErrorDeclaration {
ErrorDeclaration::new()
}
pub fn check_errors(&self) -> ErrorCheck {
ErrorCheck::new()
}
pub(in codegen) fn local_declarations(&self) -> Tokens {
if let Data::Struct(ref vd) = self.data {
let vdr = vd.as_ref().map(Field::as_declaration);
let decls = vdr.fields.as_slice();
quote!(#(#decls)*)
} else {
quote!()
}
}
pub(in codegen) fn immutable_declarations(&self) -> Tokens {
if let Data::Struct(ref vd) = self.data {
let vdr = vd.as_ref().map(|f| field::Declaration::new(f, false));
let decls = vdr.fields.as_slice();
quote!(#(#decls)*)
} else {
quote!()
}
}
pub(in codegen) fn map_fn(&self) -> Option<Tokens> {
self.map.as_ref().map(|path| quote!(.map(#path)))
}
pub(in codegen) fn fallback_decl(&self) -> Tokens {
let default = self.default.as_ref().map(DefaultExpression::as_declaration);
quote!(#default)
}
pub fn require_fields(&self) -> Tokens {
if let Data::Struct(ref vd) = self.data {
let check_nones = vd.as_ref().map(Field::as_presence_check);
let checks = check_nones.fields.as_slice();
quote!(#(#checks)*)
} else {
quote!()
}
}
pub(in codegen) fn initializers(&self) -> Tokens {
let foo = match self.data {
Data::Enum(_) => panic!("Core loop on enums isn't supported"),
Data::Struct(ref data) => {
FieldsGen(data)
}
};
foo.initializers()
}
pub(in codegen) fn core_loop(&self) -> Tokens {
let foo = match self.data {
Data::Enum(_) => panic!("Core loop on enums isn't supported"),
Data::Struct(ref data) => {
FieldsGen(data)
}
};
foo.core_loop()
}
}