use std::borrow::Cow;
use std::any::TypeId;
#[derive(Debug, Clone)]
pub struct PropertyMeta {
pub field_name: Cow<'static, str>,
pub column_name: Cow<'static, str>,
pub type_id: TypeId,
pub type_name: Cow<'static, str>,
pub is_primary_key: bool,
pub is_auto_increment: bool,
pub is_required: bool,
pub is_foreign_key: bool,
pub is_concurrency_token: bool,
pub max_length: Option<usize>,
pub is_unique: bool,
pub has_index: bool,
pub is_not_mapped: bool,
}
pub struct PropertyMetaBuilder {
meta: PropertyMeta,
}
impl PropertyMetaBuilder {
pub fn new(field_name: &'static str, type_id: TypeId, type_name: &'static str) -> Self {
Self {
meta: PropertyMeta {
field_name: Cow::Borrowed(field_name),
column_name: Cow::Borrowed(field_name),
type_id,
type_name: Cow::Borrowed(type_name),
is_primary_key: false,
is_auto_increment: false,
is_required: false,
is_foreign_key: false,
is_concurrency_token: false,
max_length: None,
is_unique: false,
has_index: false,
is_not_mapped: false,
},
}
}
pub fn column_name(mut self, name: &'static str) -> Self {
self.meta.column_name = Cow::Borrowed(name);
self
}
pub fn is_primary_key(mut self, v: bool) -> Self {
self.meta.is_primary_key = v;
self
}
pub fn is_auto_increment(mut self, v: bool) -> Self {
self.meta.is_auto_increment = v;
self
}
pub fn is_required(mut self, v: bool) -> Self {
self.meta.is_required = v;
self
}
pub fn is_foreign_key(mut self, v: bool) -> Self {
self.meta.is_foreign_key = v;
self
}
pub fn is_concurrency_token(mut self, v: bool) -> Self {
self.meta.is_concurrency_token = v;
self
}
pub fn max_length(mut self, n: usize) -> Self {
self.meta.max_length = Some(n);
self
}
pub fn is_unique(mut self, v: bool) -> Self {
self.meta.is_unique = v;
self
}
pub fn has_index(mut self, v: bool) -> Self {
self.meta.has_index = v;
self
}
pub fn is_not_mapped(mut self, v: bool) -> Self {
self.meta.is_not_mapped = v;
self
}
pub fn build(self) -> PropertyMeta {
self.meta
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NavigationKind {
BelongsTo,
HasOne,
HasMany,
}
#[derive(Debug, Clone)]
pub struct NavigationMeta {
pub field_name: Cow<'static, str>,
pub kind: NavigationKind,
pub related_type_id: TypeId,
pub related_type_name: Cow<'static, str>,
pub foreign_key_field: Option<Cow<'static, str>>,
pub inverse_navigation: Option<Cow<'static, str>>,
pub through_type_id: Option<TypeId>,
}
#[derive(Debug, Clone)]
pub struct EntityTypeMeta {
pub type_id: TypeId,
pub type_name: Cow<'static, str>,
pub table_name: Cow<'static, str>,
pub properties: Vec<PropertyMeta>,
pub navigations: Vec<NavigationMeta>,
pub primary_keys: Vec<Cow<'static, str>>,
}
impl EntityTypeMeta {
pub fn find_property(&self, field_name: &str) -> Option<&PropertyMeta> {
self.properties.iter().find(|p| p.field_name == field_name)
}
pub fn find_navigation(&self, field_name: &str) -> Option<&NavigationMeta> {
self.navigations.iter().find(|n| n.field_name == field_name)
}
pub fn primary_key_property(&self) -> Option<&PropertyMeta> {
self.properties.iter().find(|p| p.is_primary_key)
}
pub fn mapped_scalar_properties(&self) -> impl Iterator<Item = &PropertyMeta> {
self.properties.iter().filter(|p| !p.is_not_mapped)
}
}