#[cfg(test)]
mod test;
pub mod xs {
use odata_client_util::deserialize_with::flattened_xml_attr;
use serde::de::Visitor;
use serde::{Deserialize, Deserializer};
use std::{fmt, marker::PhantomData};
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct AnyUri(pub String);
#[derive(Debug, Deserialize, Clone, PartialEq, Default)]
#[serde(transparent)]
pub struct Boolean(#[serde(deserialize_with = "flattened_xml_attr")] pub bool);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct Long(#[serde(deserialize_with = "flattened_xml_attr")] pub i64);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct Double(#[serde(deserialize_with = "flattened_xml_attr")] pub f64);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct Integer(#[serde(deserialize_with = "flattened_xml_attr")] pub i64);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct NonNegativeInteger(#[serde(deserialize_with = "flattened_xml_attr")] pub u64);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct String(pub std::string::String);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct Token(pub std::string::String);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct NCName(pub std::string::String);
#[derive(Debug, Clone, PartialEq)]
pub struct List<T>(pub Vec<T>);
impl<'de, T: Deserialize<'de>> Deserialize<'de> for List<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct EdmListVisitor<T>(PhantomData<T>);
impl<'de, T: Deserialize<'de>> Visitor<'de> for EdmListVisitor<T> {
type Value = List<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("whitespace-separated list of items")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
#[derive(Debug, Deserialize, Clone, PartialEq)]
struct ListItemWrap<T> {
val: T,
}
let mut parsed_items = Vec::new();
for item_str in v.split_whitespace() {
let parsed_item = serde_xml_rs::from_str::<ListItemWrap<T>>(&format!(
"<Wrap val=\"{}\" />",
xml::escape::escape_str_attribute(item_str)
))
.map_err(|e| {
E::custom(format!("Failed to deserialize item in xs:list: {}", e))
})?;
parsed_items.push(parsed_item.val);
}
Ok(List(parsed_items))
}
}
deserializer.deserialize_str(EdmListVisitor::<T>(PhantomData))
}
}
}
pub mod edm {
use super::xs;
use lazy_static::lazy_static;
use regex::Regex;
use serde::de::Error;
use serde::{Deserialize, Deserializer};
use uuid::Uuid;
fn boolean_true() -> xs::Boolean {
xs::Boolean(true)
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Schema {
#[serde(rename = "ComplexType", default)]
pub complex_types: Vec<TComplexType>,
#[serde(rename = "EntityType", default)]
pub entity_types: Vec<TEntityType>,
#[serde(rename = "TypeDefinition", default)]
pub type_definitions: Vec<TTypeDefinition>,
#[serde(rename = "EnumType", default)]
pub enum_types: Vec<TEnumType>,
#[serde(rename = "Action", default)]
pub actions: Vec<TAction>,
#[serde(rename = "Function", default)]
pub functions: Vec<TFunction>,
#[serde(rename = "Term", default)]
pub terms: Vec<TTerm>,
#[serde(rename = "Annotations", default)]
pub annotation_groups: Vec<TAnnotations>,
#[serde(rename = "EntityContainer", default)]
pub entity_containers: Vec<TEntityContainer>,
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub namespace: TNamespaceName,
pub alias: Option<TSimpleIdentifier>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TEntityType {
pub key: Option<TEntityKeyElement>,
#[serde(rename = "Property", default)]
pub properties: Vec<TProperty>,
#[serde(rename = "NavigationProperty", default)]
pub navigation_properties: Vec<TNavigationProperty>,
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
#[serde(flatten)]
pub derivable_type_attributes: TDerivableTypeAttributes,
#[serde(default)]
pub open_type: xs::Boolean,
#[serde(default)]
pub has_stream: xs::Boolean,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TEntityKeyElement {
#[serde(rename = "PropertyRef", default)]
pub property_refs: Vec<TPropertyRef>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TPropertyRef {
pub name: TPath,
pub alias: Option<TSimpleIdentifier>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TComplexType {
#[serde(rename = "Property", default)]
pub properties: Vec<TProperty>,
#[serde(rename = "NavigationProperty", default)]
pub navigation_properties: Vec<TNavigationProperty>,
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
#[serde(flatten)]
pub derivable_type_attributes: TDerivableTypeAttributes,
#[serde(default)]
pub open_type: xs::Boolean,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TProperty {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
#[serde(flatten)]
pub common_property_attributes: TCommonPropertyAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TTypeDefinition {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub name: TSimpleIdentifier,
pub underlying_type: TPrimitiveType,
#[serde(flatten)]
pub facet_attributes: TFacetAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TNavigationProperty {
#[serde(rename = "ReferentialConstraint", default)]
pub referential_constraints: Vec<TReferentialConstraint>,
#[serde(rename = "OnDelete", default)]
pub on_deletes: Vec<TOnDelete>,
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub name: TSimpleIdentifier,
pub r#type: TTypeName,
pub nullable: Option<xs::Boolean>,
pub partner: Option<TPath>,
#[serde(default)]
pub contains_target: xs::Boolean,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TReferentialConstraint {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub property: TPath,
pub referenced_property: TPath,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TOnDelete {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub action: TOnDeleteAction,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TEnumType {
#[serde(rename = "Member", default)]
pub members: Vec<TEnumTypeMember>,
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
#[serde(flatten)]
pub type_attributes: TTypeAttributes,
#[serde(default)]
pub is_flags: xs::Boolean,
pub underlying_type: Option<TTypeName>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TEnumTypeMember {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub name: TSimpleIdentifier,
pub value: Option<xs::Long>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TActionFunctionReturnType {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub r#type: TTypeName,
pub nullable: Option<xs::Boolean>,
#[serde(flatten)]
pub facet_attributes: TFacetAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TAction {
#[serde(rename = "Parameter", default)]
pub parameters: Vec<TActionFunctionParameter>,
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
#[serde(rename = "ReturnType", default)]
pub return_types: Vec<TActionFunctionReturnType>,
#[serde(flatten)]
pub action_attributes: TActionAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TFunction {
#[serde(rename = "Parameter", default)]
pub parameters: Vec<TActionFunctionParameter>,
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub return_type: TActionFunctionReturnType,
#[serde(flatten)]
pub function_attributes: TFunctionAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TActionFunctionParameter {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
#[serde(flatten)]
pub action_function_parameter_attributes: TActionFunctionParameterAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TTerm {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub name: TSimpleIdentifier,
pub r#type: TTypeName,
pub base_term: Option<TQualifiedName>,
pub nullable: Option<xs::Boolean>,
pub default_value: Option<xs::String>,
pub applies_to: Option<TAppliesTo>,
#[serde(flatten)]
pub facet_attributes: TFacetAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TAnnotations {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub target: TTarget,
pub qualifier: Option<TSimpleIdentifier>,
}
macro_rules! with_g_inline_expressions_fields {
(
$(#[$attr:meta])*
pub struct $name:ident {
$(
$(#[$field_attr:meta])*
pub $field_name:ident: $field_type:ty,
)*
...
}
) => {
$(#[$attr])*
pub struct $name {
$(
$(#[$field_attr])*
pub $field_name: $field_type,
)*
pub binary: Option<Binary>,
pub bool: Option<Boolean>,
pub date: Option<Date>,
pub date_time_offset: Option<DateTimeStamp>,
pub decimal: Option<TDecimalLiteral>,
pub duration: Option<DayTimeDuration>,
pub enum_member: Option<TEnumMemberList>,
pub float: Option<xs::Double>,
pub guid: Option<TGuidLiteral>,
pub int: Option<xs::Integer>,
pub string: Option<xs::String>,
pub time_of_day: Option<Time>,
pub annotation_path: Option<TModelPath>,
pub model_element_path: Option<TModelPath>,
pub navigation_property_path: Option<TModelPath>,
pub path: Option<TInstancePath>,
pub property_path: Option<TModelPath>,
pub url_ref: Option<xs::AnyUri>,
}
};
}
with_g_inline_expressions_fields! {
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct Annotation {
#[serde(rename = "$value", default)]
pub expressions_annotations: Vec<GExpressionOrAnnotation>,
pub term: TQualifiedName,
pub qualifier: Option<TSimpleIdentifier>,
...
}
}
macro_rules! with_g_expression_variants {
(
$(#[$attr:meta])*
pub enum $name:ident {
$($extra_variant:ident($extra_variant_type:ident),)*
...
}
) => {
$(#[$attr])*
pub enum $name {
$(
$extra_variant($extra_variant_type),
)*
Binary(TBinaryConstantExpression),
Bool(TBoolConstantExpression),
Date(TDateConstantExpression),
DateTimeOffset(TDateTimeOffsetConstantExpression),
Decimal(TDecimalConstantExpression),
Duration(TDurationConstantExpression),
EnumMember(TEnumMemberList),
Float(TFloatConstantExpression),
Guid(TGuidConstantExpression),
Int(TIntConstantExpression),
String(TStringConstantExpression),
TimeOfDay(TTimeOfDayConstantExpression),
AnnotationPath(TModelPath),
Apply(TApplyExpression),
Cast(TCastOrIsOfExpression),
Collection(TCollectionExpression),
If(TIfExpression),
Eq(TTwoChildrenExpression),
Ne(TTwoChildrenExpression),
Ge(TTwoChildrenExpression),
Gt(TTwoChildrenExpression),
Le(TTwoChildrenExpression),
Lt(TTwoChildrenExpression),
And(TTwoChildrenExpression),
Or(TTwoChildrenExpression),
Not(TOneChildExpression),
Has(TTwoChildrenExpression),
In(TTwoChildrenExpression),
Add(TTwoChildrenExpression),
Sub(TTwoChildrenExpression),
Neg(TOneChildExpression),
Mul(TTwoChildrenExpression),
Div(TTwoChildrenExpression),
DivBy(TTwoChildrenExpression),
Mod(TTwoChildrenExpression),
IsOf(TCastOrIsOfExpression),
LabeledElement(TLabeledElementExpression),
LabeledElementReference(TLabeledElementReferenceExpression),
Null(TNullExpression),
ModelElementPath(TModelPath),
NavigationPropertyPath(TModelPath),
Path(TInstancePath),
PropertyPath(TModelPath),
Record(TRecordExpression),
UrlRef(TOneChildExpression),
}
};
}
with_g_expression_variants! {
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum GExpression { ... }
}
with_g_expression_variants! {
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum GExpressionOrAnnotation {
Annotation(Annotation),
...
}
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct GInlineExpressions {
pub binary: Option<Binary>,
pub bool: Option<Boolean>,
pub date: Option<Date>,
pub date_time_offset: Option<DateTimeStamp>,
pub decimal: Option<TDecimalLiteral>,
pub duration: Option<DayTimeDuration>,
pub enum_member: Option<TEnumMemberList>,
pub float: Option<xs::Double>,
pub guid: Option<TGuidLiteral>,
pub int: Option<xs::Integer>,
pub string: Option<xs::String>,
pub time_of_day: Option<Time>,
pub annotation_path: Option<TModelPath>,
pub model_element_path: Option<TModelPath>,
pub navigation_property_path: Option<TModelPath>,
pub path: Option<TInstancePath>,
pub property_path: Option<TModelPath>,
pub url_ref: Option<xs::AnyUri>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TBinaryConstantExpression {
#[serde(rename = "$value")]
pub val: Binary,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TBoolConstantExpression {
#[serde(rename = "$value")]
pub val: Boolean,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TDateConstantExpression {
#[serde(rename = "$value")]
pub val: Date,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TDateTimeOffsetConstantExpression {
#[serde(rename = "$value")]
pub val: DateTimeStamp,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TDecimalConstantExpression {
#[serde(rename = "$value")]
pub val: TDecimalLiteral,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TDurationConstantExpression {
#[serde(rename = "$value")]
pub val: DayTimeDuration,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TFloatConstantExpression {
#[serde(rename = "$value")]
pub val: xs::Double,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TGuidConstantExpression {
#[serde(rename = "$value")]
pub val: TGuidLiteral,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TDecimalLiteral(f64);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TGuidLiteral(Uuid);
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TIntConstantExpression {
#[serde(rename = "$value")]
pub val: xs::Integer,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TStringConstantExpression {
#[serde(rename = "$value")]
pub val: xs::String,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TTimeOfDayConstantExpression {
#[serde(rename = "$value")]
pub val: Time,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TApplyExpression {
#[serde(rename = "$value")]
pub expressions_annotations: Vec<GExpressionOrAnnotation>,
pub function: Option<TClientFunction>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TCastOrIsOfExpression {
#[serde(rename = "$value")]
pub expressions_annotations: Vec<GExpressionOrAnnotation>,
pub r#type: Option<TTypeName>,
pub max_length: Option<TMaxLengthFacet>,
pub precision: Option<TPrecisionFacet>,
pub scale: Option<TScaleFacet>,
pub srid: Option<TSridFacet>,
pub unicode: Option<TUnicodeFacet>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TCollectionExpression {
#[serde(rename = "$value", default)]
pub expressions: Vec<GExpression>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TIfExpression {
#[serde(rename = "$value")]
pub expressions_annotations: Vec<GExpressionOrAnnotation>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TOneChildExpression {
#[serde(rename = "$value")]
pub expressions_annotations: Vec<GExpressionOrAnnotation>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TTwoChildrenExpression {
#[serde(rename = "$value")]
pub expressions_annotations: Vec<GExpressionOrAnnotation>,
}
with_g_inline_expressions_fields! {
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TLabeledElementExpression {
#[serde(rename = "$value")]
pub expressions_annotations: Vec<GExpressionOrAnnotation>,
pub name: TSimpleIdentifier,
...
}
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TLabeledElementReferenceExpression {
#[serde(rename = "$value")]
pub val: TQualifiedName,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub struct TNullExpression {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TRecordExpression {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
#[serde(rename = "Annotation", default)]
pub property_value: Vec<TPropertyValue>,
pub r#type: Option<TQualifiedName>,
}
with_g_inline_expressions_fields! {
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TPropertyValue {
#[serde(rename = "$value")]
pub expressions_annotations: Vec<GExpressionOrAnnotation>,
pub property: TSimpleIdentifier,
...
}
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TFacetAttributes {
pub max_length: Option<TMaxLengthFacet>,
pub precision: Option<TPrecisionFacet>,
pub scale: Option<TScaleFacet>,
pub srid: Option<TSridFacet>,
pub unicode: Option<TUnicodeFacet>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TCommonPropertyAttributes {
pub name: TSimpleIdentifier,
pub r#type: TTypeName,
#[serde(default = "boolean_true")]
pub nullable: xs::Boolean,
pub default_value: Option<xs::String>,
#[serde(flatten)]
pub facet_attributes: TFacetAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TActionFunctionParameterAttributes {
pub name: TSimpleIdentifier,
pub r#type: TTypeName,
#[serde(default = "boolean_true")]
pub nullable: xs::Boolean,
#[serde(flatten)]
pub facet_attributes: TFacetAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TActionAttributes {
pub name: TSimpleIdentifier,
pub entity_set_path: Option<TPath>,
#[serde(default)]
pub is_bound: xs::Boolean,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TFunctionAttributes {
pub name: TSimpleIdentifier,
pub entity_set_path: Option<TPath>,
#[serde(default)]
pub is_bound: xs::Boolean,
#[serde(default)]
pub is_composable: xs::Boolean,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TTypeAttributes {
pub name: TSimpleIdentifier,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TDerivableTypeAttributes {
#[serde(flatten)]
pub type_attributes: TTypeAttributes,
pub base_type: Option<TQualifiedName>,
#[serde(default)]
pub r#abstract: xs::Boolean,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TEntityContainer {
#[serde(rename = "EntitySet", default)]
pub entity_sets: Vec<TEntitySet>,
#[serde(rename = "ActionImport", default)]
pub action_imports: Vec<TActionImport>,
#[serde(rename = "FunctionImport", default)]
pub function_imports: Vec<TFunctionImport>,
#[serde(rename = "Singleton", default)]
pub singletons: Vec<TSingleton>,
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub name: TSimpleIdentifier,
pub extends: Option<TQualifiedName>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TEntitySet {
#[serde(rename = "NavigationPropertyBinding", default)]
pub navigation_property_bindings: Vec<TNavigationPropertyBinding>,
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
#[serde(flatten)]
pub entity_set_attributes: TEntitySetAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TNavigationPropertyBinding {
pub path: TPath,
pub target: TPath,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TEntitySetAttributes {
pub name: TSimpleIdentifier,
pub entity_type: TQualifiedName,
#[serde(default = "boolean_true")]
pub include_in_service_document: xs::Boolean,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TSingleton {
#[serde(rename = "NavigationPropertyBinding", default)]
pub navigation_property_bindings: Vec<TNavigationPropertyBinding>,
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub name: TSimpleIdentifier,
pub r#type: TQualifiedName,
#[serde(default)] pub nullable: xs::Boolean,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TActionImport {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub action: TQualifiedName,
#[serde(flatten)]
pub action_function_import_attributes: TActionFunctionImportAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TFunctionImport {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<Annotation>,
pub function: TQualifiedName,
#[serde(default)]
pub include_in_service_document: xs::Boolean,
#[serde(flatten)]
pub action_function_import_attributes: TActionFunctionImportAttributes,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TActionFunctionImportAttributes {
pub name: TSimpleIdentifier,
pub entity_set: Option<TPath>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TSimpleIdentifier(pub xs::NCName);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TNamespaceName(pub xs::NCName);
#[derive(Debug, Clone, PartialEq)]
pub struct TQualifiedName(pub xs::NCName);
impl<'de> Deserialize<'de> for TQualifiedName {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
lazy_static! {
static ref T_QUALIFIED_NAME_PATTERN: Regex = Regex::new(
r#"(?x)
[\p{L}\p{Nl}_]
[\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}[[:cntrl:]]]{0,}
(
\.
[\p{L}\p{Nl}_]
[\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}[[:cntrl:]]]{0,}
){1,}
"#
)
.unwrap();
}
let string_val = String::deserialize(deserializer)?;
if T_QUALIFIED_NAME_PATTERN.is_match(&string_val) {
Ok(TQualifiedName(xs::NCName(string_val)))
} else {
Err(D::Error::custom("Value is not a valid `TQualifiedName`"))
}
}
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TEnumMemberList(pub xs::List<TPath>);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum TTypeName {
Primitive(TPrimitiveType),
Abstract(TAbstractType),
CollectionQualified(CollectionQualified),
Qualified(TQualifiedName),
}
#[derive(Debug, Clone, PartialEq)]
pub struct CollectionQualified(pub TQualifiedName);
impl<'de> Deserialize<'de> for CollectionQualified {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
lazy_static! {
static ref COLLECTION_QUALIFIED_PATTERN: Regex = Regex::new(
r#"(?x)
Collection\(
(?P<inner>
[\p{L}\p{Nl}_]
[\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}[[:cntrl:]]]{0,}
(
\.
[\p{L}\p{Nl}_]
[\p{L}\p{Nl}\p{Nd}\p{Mn}\p{Mc}\p{Pc}[[:cntrl:]]]{0,}
){1,}
)
\)
"#
)
.unwrap();
}
let string_val = String::deserialize(deserializer)?;
match COLLECTION_QUALIFIED_PATTERN.captures(&string_val) {
Some(cap) => {
let inner_val = cap["inner"].to_string();
Ok(CollectionQualified(TQualifiedName(xs::NCName(inner_val))))
}
None => Err(D::Error::custom(
"Value does not match 'Collection([TQualifiedName])'",
)),
}
}
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TPath(pub xs::String);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TInstancePath(pub xs::String);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TModelPath(pub xs::String);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TTarget(pub xs::String);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum TClientFunction {
Qualified(TQualifiedName),
BuiltIn(BuiltInClientFunction),
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum BuiltInClientFunction {
#[serde(rename = "odata.concat")]
OdataConcat,
#[serde(rename = "odata.contains")]
OdataContains,
#[serde(rename = "odata.endswith")]
OdataEndswith,
#[serde(rename = "odata.indexof")]
OdataIndexof,
#[serde(rename = "odata.length")]
OdataLength,
#[serde(rename = "odata.startswith")]
OdataStartswith,
#[serde(rename = "odata.substring")]
OdataSubstring,
#[serde(rename = "odata.hassubset")]
OdataHassubset,
#[serde(rename = "odata.hassubsequence")]
OdataHassubsequence,
#[serde(rename = "odata.tolower")]
OdataTolower,
#[serde(rename = "odata.toupper")]
OdataToupper,
#[serde(rename = "odata.trim")]
OdataTrim,
#[serde(rename = "odata.date")]
OdataDate,
#[serde(rename = "odata.day")]
OdataDay,
#[serde(rename = "odata.fractionalseconds")]
OdataFractionalSeconds,
#[serde(rename = "odata.hour")]
OdataHour,
#[serde(rename = "odata.maxdatetime")]
OdataMaxdatetime,
#[serde(rename = "odata.mindatetime")]
OdataMindatetime,
#[serde(rename = "odata.minute")]
OdataMinute,
#[serde(rename = "odata.month")]
OdataMonth,
#[serde(rename = "odata.now")]
OdataNow,
#[serde(rename = "odata.second")]
OdataSecond,
#[serde(rename = "odata.time")]
OdataTime,
#[serde(rename = "odata.totaloffsetminutes")]
OdataTotaloffsetminutes,
#[serde(rename = "odata.totalseconds")]
OdataTotalseconds,
#[serde(rename = "odata.year")]
OdataYear,
#[serde(rename = "odata.ceiling")]
OdataCeiling,
#[serde(rename = "odata.floor")]
OdataCloor,
#[serde(rename = "odata.round")]
OdataRound,
#[serde(rename = "odata.cast")]
OdataCast,
#[serde(rename = "odata.isof")]
OdataIsof,
#[serde(rename = "odata.geo.distance")]
OdataGeoDistance,
#[serde(rename = "odata.geo.intersects")]
OdataGeoIntersects,
#[serde(rename = "odata.geo.length")]
OdataGeoLength,
#[serde(rename = "odata.fillUriTemplate")]
OdataFillUriTemplate,
#[serde(rename = "odata.uriEncode")]
OdataUriEncode,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum TPrimitiveType {
#[serde(rename = "Edm.Binary")]
EdmBinary,
#[serde(rename = "Edm.Boolean")]
EdmBoolean,
#[serde(rename = "Edm.Byte")]
EdmByte,
#[serde(rename = "Edm.Date")]
EdmDate,
#[serde(rename = "Edm.DateTimeOffset")]
EdmDateTimeOffset,
#[serde(rename = "Edm.Duration")]
EdmDuration,
#[serde(rename = "Edm.TimeOfDay")]
EdmTimeOfDay,
#[serde(rename = "Edm.Decimal")]
EdmDecimal,
#[serde(rename = "Edm.Double")]
EdmDouble,
#[serde(rename = "Edm.Single")]
EdmSingle,
#[serde(rename = "Edm.GeographyPoint")]
EdmGeographyPoint,
#[serde(rename = "Edm.GeographyLineString")]
EdmGeographyLineString,
#[serde(rename = "Edm.GeographyPolygon")]
EdmGeographyPolygon,
#[serde(rename = "Edm.GeographyMultiPoint")]
EdmGeographyMultiPoint,
#[serde(rename = "Edm.GeographyMultiLineString")]
EdmGeographyMultiLineString,
#[serde(rename = "Edm.GeographyMultiPolygon")]
EdmGeographyMultiPolygon,
#[serde(rename = "Edm.GeographyCollection")]
EdmGeographyCollection,
#[serde(rename = "Edm.GeometryPoint")]
EdmGeometryPoint,
#[serde(rename = "Edm.GeometryLineString")]
EdmGeometryLineString,
#[serde(rename = "Edm.GeometryPolygon")]
EdmGeometryPolygon,
#[serde(rename = "Edm.GeometryMultiPoint")]
EdmGeometryMultiPoint,
#[serde(rename = "Edm.GeometryMultiLineString")]
EdmGeometryMultiLineString,
#[serde(rename = "Edm.GeometryMultiPolygon")]
EdmGeometryMultiPolygon,
#[serde(rename = "Edm.GeometryCollection")]
EdmGeometryCollection,
#[serde(rename = "Edm.Guid")]
EdmGuid,
#[serde(rename = "Edm.Int16")]
EdmInt16,
#[serde(rename = "Edm.Int32")]
EdmInt32,
#[serde(rename = "Edm.Int64")]
EdmInt64,
#[serde(rename = "Edm.String")]
EdmString,
#[serde(rename = "Edm.SByte")]
EdmSByte,
#[serde(rename = "Collection(Edm.Binary)")]
CollectionEdmBinary,
#[serde(rename = "Collection(Edm.Boolean)")]
CollectionEdmBoolean,
#[serde(rename = "Collection(Edm.Byte)")]
CollectionEdmByte,
#[serde(rename = "Collection(Edm.Date)")]
CollectionEdmDate,
#[serde(rename = "Collection(Edm.DateTimeOffset)")]
CollectionEdmDateTimeOffset,
#[serde(rename = "Collection(Edm.Duration)")]
CollectionEdmDuration,
#[serde(rename = "Collection(Edm.TimeOfDay)")]
CollectionEdmTimeOfDay,
#[serde(rename = "Collection(Edm.Decimal)")]
CollectionEdmDecimal,
#[serde(rename = "Collection(Edm.Double)")]
CollectionEdmDouble,
#[serde(rename = "Collection(Edm.Single)")]
CollectionEdmSingle,
#[serde(rename = "Collection(Edm.GeographyPoint)")]
CollectionEdmGeographyPoint,
#[serde(rename = "Collection(Edm.GeographyLineString)")]
CollectionEdmGeographyLineString,
#[serde(rename = "Collection(Edm.GeographyPolygon)")]
CollectionEdmGeographyPolygon,
#[serde(rename = "Collection(Edm.GeographyMultiPoint)")]
CollectionEdmGeographyMultiPoint,
#[serde(rename = "Collection(Edm.GeographyMultiLineString)")]
CollectionEdmGeographyMultiLineString,
#[serde(rename = "Collection(Edm.GeographyMultiPolygon)")]
CollectionEdmGeographyMultiPolygon,
#[serde(rename = "Collection(Edm.GeographyCollection)")]
CollectionEdmGeographyCollection,
#[serde(rename = "Collection(Edm.GeometryPoint)")]
CollectionEdmGeometryPoint,
#[serde(rename = "Collection(Edm.GeometryLineString)")]
CollectionEdmGeometryLineString,
#[serde(rename = "Collection(Edm.GeometryPolygon)")]
CollectionEdmGeometryPolygon,
#[serde(rename = "Collection(Edm.GeometryMultiPoint)")]
CollectionEdmGeometryMultiPoint,
#[serde(rename = "Collection(Edm.GeometryMultiLineString)")]
CollectionEdmGeometryMultiLineString,
#[serde(rename = "Collection(Edm.GeometryMultiPolygon)")]
CollectionEdmGeometryMultiPolygon,
#[serde(rename = "Collection(Edm.GeometryCollection)")]
CollectionEdmGeometryCollection,
#[serde(rename = "Collection(Edm.Guid)")]
CollectionEdmGuid,
#[serde(rename = "Collection(Edm.Int16)")]
CollectionEdmInt16,
#[serde(rename = "Collection(Edm.Int32)")]
CollectionEdmInt32,
#[serde(rename = "Collection(Edm.Int64)")]
CollectionEdmInt64,
#[serde(rename = "Collection(Edm.String)")]
CollectionEdmString,
#[serde(rename = "Collection(Edm.SByte)")]
CollectionEdmSByte,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum TAbstractType {
#[serde(rename = "Edm.ComplexType")]
EdmComplexType,
#[serde(rename = "Edm.EntityType")]
EdmEntityType,
#[serde(rename = "Edm.PrimitiveType")]
EdmPrimitiveType,
#[serde(rename = "Edm.Untyped")]
EdmUntyped,
#[serde(rename = "Edm.Geography")]
EdmGeography,
#[serde(rename = "Edm.Geometry")]
EdmGeometry,
#[serde(rename = "Edm.AnnotationPath")]
EdmAnnotationPath,
#[serde(rename = "Edm.AnyPropertyPath")]
EdmAnyPropertyPath,
#[serde(rename = "Edm.ModelElementPath")]
EdmModelElementPath,
#[serde(rename = "Edm.NavigationPropertyPath")]
EdmNavigationPropertyPath,
#[serde(rename = "Edm.PropertyPath")]
EdmPropertyPath,
#[serde(rename = "Collection(Edm.ComplexType)")]
CollectionEdmComplexType,
#[serde(rename = "Collection(Edm.EntityType)")]
CollectionEdmEntityType,
#[serde(rename = "Collection(Edm.PrimitiveType)")]
CollectionEdmPrimitiveType,
#[serde(rename = "Collection(Edm.Untyped)")]
CollectionEdmUntyped,
#[serde(rename = "Collection(Edm.Geography)")]
CollectionEdmGeography,
#[serde(rename = "Collection(Edm.Geometry)")]
CollectionEdmGeometry,
#[serde(rename = "Collection(Edm.AnnotationPath)")]
CollectionEdmAnnotationPath,
#[serde(rename = "Collection(Edm.AnyPropertyPath)")]
CollectionEdmAnyPropertyPath,
#[serde(rename = "Collection(Edm.ModelElementPath)")]
CollectionEdmModelElementPath,
#[serde(rename = "Collection(Edm.NavigationPropertyPath)")]
CollectionEdmNavigationPropertyPath,
#[serde(rename = "Collection(Edm.PropertyPath)")]
CollectionEdmPropertyPath,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum TAppliesTo {
AppliesToElements(TAppliesToElements),
SimpleIdentifier(TSimpleIdentifier),
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TAppliesToElements(pub xs::List<AppliesToElementsInner>);
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum AppliesToElementsInner {
Action,
ActionImport,
Annotation,
Apply,
Cast,
Collection,
ComplexType,
EntityContainer,
EntitySet,
EntityType,
EnumType,
Function,
FunctionImport,
If,
Include,
IsOf,
LabeledElement,
Member,
NavigationProperty,
Null,
OnDelete,
Parameter,
Property,
PropertyValue,
Record,
Reference,
ReferentialConstraint,
ReturnType,
Schema,
Singleton,
Term,
TypeDefinition,
UrlRef,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum TFloating {
#[serde(rename = "floating")]
Floating,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum TMax {
#[serde(rename = "max")]
Max,
}
#[derive(Debug, Clone, PartialEq)]
pub enum TVariable {
Variable,
}
impl<'de> Deserialize<'de> for TVariable {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let string_val = String::deserialize(deserializer)?;
match string_val.to_ascii_lowercase() == "variable" {
true => Ok(TVariable::Variable),
false => Err(D::Error::custom(format!(
"Expected `\"variable\"`, found {}",
string_val
))),
}
}
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum TMaxLengthFacet {
Max(TMax),
NonNegativeInteger(xs::NonNegativeInteger),
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TPrecisionFacet(pub xs::NonNegativeInteger);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum TScaleFacet {
Floating(TFloating),
Variable(TVariable),
NonNegativeInteger(xs::NonNegativeInteger),
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum TSridFacet {
Variable(TVariable),
NonNegativeInteger(xs::NonNegativeInteger),
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct TUnicodeFacet(pub xs::Boolean);
#[derive(Debug, Deserialize, Clone, PartialEq)]
pub enum TOnDeleteAction {
Cascade,
None,
SetDefault,
SetNull,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct Binary(pub xs::String);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct Boolean(pub xs::Boolean);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct Date(pub String);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct Time(pub String);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct DateTimeStamp(pub String);
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(transparent)]
pub struct DayTimeDuration(pub String);
}
pub mod edmx {
use super::{edm, xs};
use serde::de::Error;
use serde::{Deserialize, Deserializer};
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TEdmx {
pub version: TVersion,
#[serde(rename = "Reference", default)]
pub references: Vec<TReference>,
pub data_services: TDataServices,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TReference {
pub uri: xs::AnyUri,
#[serde(rename = "Include", default)]
pub includes: Vec<TInclude>,
#[serde(rename = "IncludeAnnotations", default)]
pub include_annotations: Vec<TIncludeAnnotations>,
#[serde(rename = "Annotation", default)]
pub annotations: Vec<edm::Annotation>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TInclude {
#[serde(rename = "Annotation", default)]
pub annotations: Vec<edm::Annotation>,
pub namespace: edm::TNamespaceName,
pub alias: Option<edm::TSimpleIdentifier>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TIncludeAnnotations {
pub term_namespace: edm::TNamespaceName,
pub qualifier: Option<edm::TSimpleIdentifier>,
pub target_namespace: Option<edm::TNamespaceName>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "PascalCase")]
pub struct TDataServices {
#[serde(rename = "Schema", default)]
pub schemas: Vec<edm::Schema>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum TVersion {
V4_0,
V4_01,
}
impl<'de> Deserialize<'de> for TVersion {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let string_val = String::deserialize(deserializer)?;
match string_val.as_str() {
"4.0" => Ok(TVersion::V4_0),
"4.01" => Ok(TVersion::V4_01),
s => Err(D::Error::custom(format!(
"Only EDMX versions 4.0 and 4.01 supported; found version value \"{}\"",
s
))),
}
}
}
}