pub mod construct;
pub mod definition_lookup;
pub mod identifiers;
mod primitive_type_defs;
#[cfg(test)]
mod test;
use std::fmt::Display;
use primitive_type_defs::{PrimitiveProperty, PrimitiveType};
use self::{
definition_lookup::{EdmItem, EdmRef, NamedEdmItem},
identifiers::{QualifiedName, TargetPath},
};
#[derive(Debug)]
pub struct EntityModel<'arena> {
pub service_url: String,
pub schemas: Vec<Schema<'arena>>,
}
#[derive(Debug)]
pub struct Schema<'a> {
pub namespace: &'a str,
pub alias: Option<&'a str>,
pub complex_types: Vec<&'a ComplexType<'a>>,
pub entity_types: Vec<&'a EntityType<'a>>,
pub primitive_aliases: Vec<&'a PrimitiveTypeAlias<'a>>,
pub enum_types: Vec<&'a EnumType<'a>>,
pub entity_container: &'a EntityContainer<'a>,
}
impl<'a> EdmItem for Schema<'a> {}
impl<'a> NamedEdmItem for Schema<'a> {
type Name = &'a str;
fn name(&self) -> Self::Name {
self.namespace
}
}
#[derive(Debug)]
pub struct ComplexishType<'a, BaseType: EdmItem + NamedEdmItem<Name = QualifiedName<'a>>> {
pub name: QualifiedName<'a>,
pub base_type: Option<EdmRef<'a, BaseType, QualifiedName<'a>>>,
pub is_open_type: bool,
pub is_abstract: bool,
pub properties: Vec<&'a Property<'a>>,
pub nav_properties: Vec<&'a NavigationProperty<'a>>,
}
#[derive(Debug)]
pub struct ComplexType<'a>(pub ComplexishType<'a, ComplexType<'a>>);
impl<'a> EdmItem for ComplexType<'a> {}
impl<'a> NamedEdmItem for ComplexType<'a> {
type Name = QualifiedName<'a>;
fn name(&self) -> Self::Name {
self.0.name
}
}
type KeyPropertiesRef<'a> =
EdmRef<'a, Option<Vec<KeyProperty<'a>>>, &'a Option<Vec<KeyProperty<'a>>>>;
impl<'a> EdmItem for Vec<KeyProperty<'a>> {
fn item_type_name() -> &'static str {
"Key"
}
}
#[derive(Debug)]
pub struct EntityType<'a> {
pub complex_type_fields: ComplexishType<'a, EntityType<'a>>,
pub has_stream: bool,
pub key_properties: KeyPropertiesRef<'a>,
}
impl<'a> EdmItem for EntityType<'a> {}
impl<'a> NamedEdmItem for EntityType<'a> {
type Name = QualifiedName<'a>;
fn name(&self) -> Self::Name {
self.complex_type_fields.name
}
}
#[derive(Debug)]
pub struct KeyProperty<'a> {
pub property: EdmRef<'a, Property<'a>, TargetPath<'a>>,
pub alias: Option<String>,
}
#[derive(Debug)]
pub struct PropertyVariantLookupKey<'a> {
pub qualified_name: QualifiedName<'a>,
pub default_value_str: Option<String>,
}
impl<'a> Display for PropertyVariantLookupKey<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.default_value_str {
None => f.write_fmt(format_args!("{}", self.qualified_name)),
Some(default_value_str) => f.write_fmt(format_args!(
"{} ({})",
self.qualified_name, default_value_str
)),
}
}
}
#[derive(Debug)]
pub struct Property<'a> {
pub name: TargetPath<'a>,
pub r#type: EdmRef<'a, PropertyVariant<'a>, PropertyVariantLookupKey<'a>>,
pub nullable: bool,
pub is_collection: bool,
}
impl<'a> EdmItem for Property<'a> {}
impl<'a> NamedEdmItem for Property<'a> {
type Name = TargetPath<'a>;
fn name(&self) -> Self::Name {
self.name
}
}
#[derive(Debug)]
pub enum PropertyVariant<'a> {
Primitive(PrimitiveProperty),
Abstract,
PrimitiveAlias(&'a PrimitiveTypeAlias<'a>),
Complex(&'a ComplexType<'a>),
Enumeration {
enum_type: &'a EnumType<'a>,
default_value: Option<i64>,
},
}
impl<'a> EdmItem for PropertyVariant<'a> {
fn item_type_name() -> &'static str {
"[Nominal/Primitive/Abstract type]"
}
}
#[derive(Debug)]
pub struct PrimitiveTypeAlias<'a> {
pub name: QualifiedName<'a>,
pub r#type: PrimitiveType,
pub is_collection: bool,
}
impl<'a> EdmItem for PrimitiveTypeAlias<'a> {
fn item_type_name() -> &'static str {
"TypeDefinition"
}
}
impl<'a> NamedEdmItem for PrimitiveTypeAlias<'a> {
type Name = QualifiedName<'a>;
fn name(&self) -> Self::Name {
self.name
}
}
#[derive(Debug)]
pub struct NavigationProperty<'a> {
pub name: TargetPath<'a>,
pub r#type: NavigationPropertyVariant<'a>,
pub type_modifier: NavigationPropertyModifier,
pub referential_constraints: Vec<ReferentialConstraint<'a>>,
pub on_delete_action: Option<OnDeleteAction>,
pub partner: Option<EdmRef<'a, NavigationProperty<'a>, TargetPath<'a>>>,
pub contains_target: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub enum NavigationPropertyModifier {
NonNull,
Collection,
Nullable,
}
impl<'a> EdmItem for NavigationProperty<'a> {}
impl<'a> NamedEdmItem for NavigationProperty<'a> {
type Name = TargetPath<'a>;
fn name(&self) -> Self::Name {
self.name
}
}
#[derive(Debug)]
pub enum NavigationPropertyVariant<'a> {
Abstract, Entity(EdmRef<'a, EntityType<'a>, QualifiedName<'a>>),
}
#[derive(Debug)]
pub struct ReferentialConstraint<'a> {
pub property: EdmRef<'a, Property<'a>, TargetPath<'a>>,
pub referenced_property: EdmRef<'a, Property<'a>, TargetPath<'a>>,
}
impl<'a> EdmItem for ReferentialConstraint<'a> {}
pub type OnDeleteAction = crate::entity_data_model_parse::edm::TOnDeleteAction;
#[derive(Debug, PartialEq)]
pub struct EnumType<'a> {
pub name: QualifiedName<'a>,
pub members: Vec<EnumTypeMember>,
pub is_flags: bool,
pub underlying_type: EnumUnderlyingType,
}
impl<'a> EdmItem for EnumType<'a> {}
impl<'a> NamedEdmItem for EnumType<'a> {
type Name = QualifiedName<'a>;
fn name(&self) -> Self::Name {
self.name
}
}
#[derive(Debug, PartialEq)]
pub enum EnumUnderlyingType {
Byte,
SByte,
Int16,
Int32,
Int64,
}
#[derive(Debug, PartialEq)]
pub struct EnumTypeMember {
pub name: String,
pub value: i64,
}
#[derive(Debug)]
pub struct EntityContainer<'a> {
pub name: QualifiedName<'a>,
pub extends: Option<EdmRef<'a, EntityContainer<'a>, QualifiedName<'a>>>,
pub entity_sets: Vec<&'a EntitySet<'a>>,
pub singletons: Vec<&'a Singleton<'a>>,
}
impl<'a> EdmItem for EntityContainer<'a> {}
impl<'a> NamedEdmItem for EntityContainer<'a> {
type Name = QualifiedName<'a>;
fn name(&self) -> Self::Name {
self.name
}
}
#[derive(Debug)]
pub struct EntitySet<'a> {
pub name: TargetPath<'a>,
pub entity_type: EdmRef<'a, EntityType<'a>, QualifiedName<'a>>,
pub include_in_service_document: bool,
pub navigation_property_bindings: Vec<NavigationPropertyBinding<'a>>,
}
impl<'a> EdmItem for EntitySet<'a> {}
impl<'a> NamedEdmItem for EntitySet<'a> {
type Name = TargetPath<'a>;
fn name(&self) -> Self::Name {
self.name
}
}
#[derive(Debug)]
pub struct NavigationPropertyBinding<'a> {
pub path: EdmRef<'a, NavigationProperty<'a>, TargetPath<'a>>,
pub target: EdmRef<'a, EntitySet<'a>, TargetPath<'a>>,
}
impl<'a> EdmItem for NavigationPropertyBinding<'a> {}
#[derive(Debug)]
pub struct Singleton<'a> {
pub name: TargetPath<'a>,
pub entity_type: EdmRef<'a, EntityType<'a>, QualifiedName<'a>>,
pub nullable: bool,
pub navigation_property_bindings: Vec<NavigationPropertyBinding<'a>>,
}
impl<'a> EdmItem for Singleton<'a> {}
impl<'a> NamedEdmItem for Singleton<'a> {
type Name = TargetPath<'a>;
fn name(&self) -> Self::Name {
self.name
}
}