use crate::attr_parser::{NamedAttribute, NamedAttributes};
use crate::field_def::FieldDef;
use crate::info_parser::schema_parser::SchemaParser;
use serde::{Deserialize, Serialize};
use std::borrow::Cow;
use syn::DeriveInput;
#[derive(Debug, PartialEq, Clone, Default)]
pub struct TableDef<'a> {
pub struct_name: Cow<'a, str>,
pub table_name: Cow<'a, str>,
pub fields: Vec<FieldDef<'a>>,
pub serde_structs: Vec<Cow<'a, str>>,
pub primary_fields: Vec<Cow<'a, str>>,
pub uniques: Vec<NamedFieldsGroup<'a>>,
pub indexes: Vec<NamedFieldsGroup<'a>>,
}
impl<'a> TableDef<'a> {
pub fn parse(input: &'a DeriveInput) -> TableDef<'a> {
SchemaParser::parse(&input)
}
pub fn get_primary_fields(&'a self) -> Vec<&'a FieldDef<'a>> {
self.filter(&self.primary_fields)
}
pub fn get_not_primary_fields(&'a self) -> Vec<&'a FieldDef<'a>> {
self.filter_not_in(&self.primary_fields)
}
pub fn get_unique_names(&'a self) -> Vec<Cow<'a, str>> {
self.uniques.iter().map(|u| u.name.clone()).collect()
}
pub fn get_index_names(&'a self) -> Vec<Cow<'a, str>> {
self.indexes.iter().map(|u| u.name.clone()).collect()
}
pub fn get_unique_fields(&'a self, name: &str) -> Vec<&'a FieldDef<'a>> {
let unique = self.uniques.iter().find(|u| u.name == name);
if let Some(unique) = unique {
self.filter(&unique.fields)
} else {
Vec::new()
}
}
pub fn get_index_fields(&'a self, name: &str) -> Vec<&'a FieldDef<'a>> {
let index = self.indexes.iter().find(|u| u.name == name);
if let Some(index) = index {
self.filter(&index.fields)
} else {
Vec::new()
}
}
fn filter(&'a self, names: &[Cow<'a, str>]) -> Vec<&'a FieldDef<'a>> {
self.fields
.iter()
.filter(|f| names.iter().any(|a| a == f.origin_column_name()))
.collect::<Vec<_>>()
}
fn filter_not_in(&'a self, names: &[Cow<'a, str>]) -> Vec<&'a FieldDef<'a>> {
self.fields
.iter()
.filter(|f| names.iter().all(|a| a != f.origin_column_name()))
.collect::<Vec<_>>()
}
}
#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize)]
pub struct NamedFieldsGroup<'a> {
pub name: Cow<'a, str>,
pub fields: Vec<Cow<'a, str>>,
}
pub fn translate_attr_groups(attrs: NamedAttributes) -> Vec<NamedFieldsGroup> {
let mut groups: Vec<NamedFieldsGroup> = vec![];
for attr in attrs.attrs.iter() {
let mut named = NamedFieldsGroup::default();
named.name = attr.name.clone();
named.fields = attr.values.clone();
groups.push(named);
}
groups
}
impl<'a> From<NamedAttribute<'a>> for NamedFieldsGroup<'a> {
fn from(attr: NamedAttribute<'a>) -> NamedFieldsGroup<'a> {
NamedFieldsGroup {
name: attr.name,
fields: attr.values,
}
}
}