use crate::part_1::v3_1::key::Key;
use serde::de::{Error, Visitor};
use serde::{Deserialize, Deserializer, Serialize};
use std::fmt;
use strum::EnumString;
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize, Default)]
pub struct ReferenceInner {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "referredSemanticId")]
pub referred_semantic_id: Option<Box<Reference>>,
pub keys: Vec<Key>,
}
#[derive(EnumString, Clone, PartialEq, Debug, Deserialize, Serialize)]
#[serde(tag = "type")]
pub enum Reference {
ExternalReference(ReferenceInner),
ModelReference(ReferenceInner),
}
impl ReferenceInner {
pub fn new(key: Key) -> Self {
Self {
referred_semantic_id: None,
keys: vec![key],
}
}
pub fn from_vec(keys: Vec<Key>) -> Self {
Self {
referred_semantic_id: None,
keys,
}
}
}
pub fn deserialize_model_reference<'de, D>(deserializer: D) -> Result<Reference, D::Error>
where
D: Deserializer<'de>,
{
struct SubmodelsVisitor;
impl<'de> Visitor<'de> for SubmodelsVisitor {
type Value = Reference;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an optional sequence of ModelReference")
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let reference: Reference = Reference::deserialize(deserializer)?;
if let Reference::ModelReference(model_ref_inner) = reference {
Ok(Reference::ModelReference(model_ref_inner))
} else {
Err(D::Error::custom("unexpected reference type"))
}
}
}
deserializer.deserialize_option(SubmodelsVisitor)
}
pub fn deserialize_external_reference<'de, D>(deserializer: D) -> Result<Reference, D::Error>
where
D: Deserializer<'de>,
{
struct SubmodelsVisitor;
impl<'de> Visitor<'de> for SubmodelsVisitor {
type Value = Reference;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an optional sequence of ModelReference")
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let reference: Reference = Reference::deserialize(deserializer)?;
if let Reference::ExternalReference(model_ref_inner) = reference {
Ok(Reference::ExternalReference(model_ref_inner))
} else {
Err(D::Error::custom("unexpected reference type"))
}
}
}
deserializer.deserialize_option(SubmodelsVisitor)
}
pub fn deserialize_optional_model_reference<'de, D>(
deserializer: D,
) -> Result<Option<Reference>, D::Error>
where
D: Deserializer<'de>,
{
struct SubmodelsVisitor;
impl<'de> Visitor<'de> for SubmodelsVisitor {
type Value = Option<Reference>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an optional sequence of ModelReference")
}
fn visit_none<E>(self) -> Result<Self::Value, E> {
Ok(None)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let reference: Reference = Reference::deserialize(deserializer)?;
if let Reference::ModelReference(model_ref_inner) = reference {
Ok(Some(Reference::ModelReference(model_ref_inner)))
} else {
Err(D::Error::custom("unexpected reference type"))
}
}
}
deserializer.deserialize_option(SubmodelsVisitor)
}
pub fn deserialize_optional_external_reference<'de, D>(
deserializer: D,
) -> Result<Option<Reference>, D::Error>
where
D: Deserializer<'de>,
{
struct SubmodelsVisitor;
impl<'de> Visitor<'de> for SubmodelsVisitor {
type Value = Option<Reference>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an optional sequence of ModelReference")
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
let reference: Reference = Reference::deserialize(deserializer)?;
if let Reference::ExternalReference(model_ref_inner) = reference {
Ok(Some(Reference::ExternalReference(model_ref_inner)))
} else {
Err(D::Error::custom("unexpected reference type"))
}
}
}
deserializer.deserialize_option(SubmodelsVisitor)
}