use std::ops::Deref;
use syn::{Expr, ExprTuple, Ident, Type, TypeTuple};
use crate::args::EntryArgs;
pub(super) struct ValueMeta<'a>(Vec<&'a EntryArgs>);
impl<'a> Deref for ValueMeta<'a> {
type Target = Vec<&'a EntryArgs>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a> ValueMeta<'a> {
pub(crate) fn new<I: 'a>(fields: I) -> Self
where
I: IntoIterator<Item = &'a EntryArgs>,
{
Self(fields.into_iter().collect())
}
pub(crate) fn new_merged(a: &'a Self, b: &'a Self) -> Self {
Self::new(a.iter().chain(b.iter()).map(|var| *var))
}
pub(crate) fn model_ty(&self) -> Type {
match self.0.len() {
1 => self[0].model_ty().clone(),
_ => {
let mut ty_el = syn::punctuated::Punctuated::new();
ty_el.extend(self.iter().map(|var| var.model_ty().to_owned()));
Type::Tuple(TypeTuple {
paren_token: Default::default(),
elems: ty_el,
})
}
}
}
pub(crate) fn redb_ty(&self) -> Type {
match self.len() {
1 => self[0].redb_ty().clone(),
_ => {
let mut ty_el = syn::punctuated::Punctuated::new();
ty_el.extend(self.iter().map(|var| var.redb_ty().to_owned()));
Type::Tuple(TypeTuple {
paren_token: Default::default(),
elems: ty_el,
})
}
}
}
pub(crate) fn idents(&self) -> impl ExactSizeIterator<Item = &Ident> {
self.iter().map(|var| var.ident())
}
pub(crate) fn composite_idents(&self) -> Expr {
match self.len() {
1 => self[0].ident_expr(),
_ => {
let mut elems = syn::punctuated::Punctuated::new();
elems.extend(self.iter().map(|var| var.ident_expr()));
Expr::Tuple(ExprTuple {
attrs: vec![],
paren_token: Default::default(),
elems,
})
}
}
}
pub(crate) fn from_methods(&'a self) -> impl ExactSizeIterator<Item = Expr> + 'a {
self.iter().map(|var| var.from_op())
}
pub(crate) fn into_methods(&'a self) -> impl ExactSizeIterator<Item = Expr> + 'a {
self.iter().map(|var| var.into_op())
}
}