use crate::attr_parser::AttrParser;
use crate::field_def::TableColumnDef;
use std::borrow::Cow;
use syn::{Attribute, Field};
pub struct FieldAttrParser;
impl FieldAttrParser {
pub fn parse<'a>(field: &'a Field, external_column_name: Option<String>) -> TableColumnDef<'a> {
let field_attr = AttrParser::get_attr(&field.attrs, "field");
let mut table_column_def: TableColumnDef = if let Some(attr) = field_attr {
FieldAttrParser::parse_field_attr(&attr)
} else {
TableColumnDef::default()
};
if let Some(column_name) = external_column_name {
if table_column_def.name.is_none() {
table_column_def.name = Some(Cow::Owned(column_name));
}
}
table_column_def
}
fn parse_bool(value: Option<Cow<'_, str>>) -> bool {
if let Some(value) = value {
value == "true"
} else {
false
}
}
pub fn parse_field_attr<'a>(attr: &'a Attribute) -> TableColumnDef<'a> {
if !AttrParser::is_attr(attr, "field") {
panic!("attribute is not named as #[field]")
}
let named_attrs = AttrParser::parse_list(attr);
let name_attr = named_attrs.iter().find(|a| a.name == Cow::Borrowed("name"));
let name = name_attr.map(|a| a.values[0].clone());
let name_attr = named_attrs
.iter()
.find(|a| a.name == Cow::Borrowed("column_type"));
let column_type = name_attr.map(|a| a.values[0].clone());
let default_attr = named_attrs
.iter()
.find(|a| a.name == Cow::Borrowed("default_value"));
let default_value = default_attr.map(|a| a.values[0].clone());
let generated_attr = named_attrs
.iter()
.find(|a| a.name == Cow::Borrowed("generated"));
let generated = generated_attr.map(|a| a.values[0].clone());
let nullable_attr = named_attrs
.iter()
.find(|a| a.name == Cow::Borrowed("nullable"));
let nullable_opt = nullable_attr.map(|a| a.values[0].clone());
let nullable = Self::parse_bool(nullable_opt);
let auto_inc_attr = named_attrs
.iter()
.find(|a| a.name == Cow::Borrowed("auto_inc"));
let auto_inc_opt = auto_inc_attr.map(|a| a.values[0].clone());
let auto_inc = Self::parse_bool(auto_inc_opt);
TableColumnDef {
name,
column_type,
default_value,
nullable,
generated,
auto_inc,
}
}
}