use crate::StruqtureError;
use std::fmt::Display;
use std::str::FromStr;
use crate::STRUQTURE_VERSION;
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "json_schema", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "json_schema", schemars(deny_unknown_fields))]
pub struct StruqtureSerialisationMeta {
pub(crate) type_name: String,
pub(crate) min_version: (usize, usize, usize),
pub(crate) version: String,
}
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct TargetSerialisationMeta {
pub(crate) type_name: String,
pub(crate) version: String,
}
pub fn check_can_be_deserialised(
target: &TargetSerialisationMeta,
source: &StruqtureSerialisationMeta,
) -> Result<(), StruqtureError> {
if target.type_name != source.type_name {
return Err(StruqtureError::TypeMismatch {
source_type: source.type_name.clone(),
target_type: target.type_name.clone(),
});
}
let (target_supported_major, target_supported_minor, _) =
semver_to_tuple(target.version.as_str())?;
if target_supported_major as usize != source.min_version.0 {
return Err(StruqtureError::NewVersionMismatch {
library_major_version: target_supported_major,
library_minor_version: target_supported_minor,
data_major_version: source.min_version.0 as u32,
data_minor_version: source.min_version.1 as u32,
name_type: source.type_name.clone(),
});
}
if (target_supported_minor as usize) < source.min_version.1 {
return Err(StruqtureError::NewVersionMismatch {
library_major_version: target_supported_major,
library_minor_version: target_supported_minor,
data_major_version: source.min_version.0 as u32,
data_minor_version: source.min_version.1 as u32,
name_type: source.type_name.clone(),
});
}
Ok(())
}
pub trait SerializationSupport {
fn min_supported_version(&self) -> (usize, usize, usize) {
(2, 0, 0)
}
fn struqture_type() -> StruqtureType;
fn struqture_serialisation_meta(&self) -> StruqtureSerialisationMeta {
StruqtureSerialisationMeta {
type_name: Self::struqture_type().to_string(),
min_version: self.min_supported_version(),
version: STRUQTURE_VERSION.to_string(),
}
}
fn target_serialisation_meta() -> TargetSerialisationMeta {
TargetSerialisationMeta {
type_name: Self::struqture_type().to_string(),
version: STRUQTURE_VERSION.to_string(),
}
}
}
fn semver_to_tuple(version: &str) -> Result<(u32, u32, u32), StruqtureError> {
let rsplit: Vec<&str> = version.splitn(3, '.').collect();
if !rsplit.len() == 3 {
return Err(StruqtureError::GenericError {
msg: format!("Invalid semver version: {version}"),
});
}
let major_version = u32::from_str(rsplit[0]).map_err(|_| StruqtureError::GenericError {
msg: format!("Invalid semver version: {version}"),
})?;
let minor_version = u32::from_str(rsplit[1]).map_err(|_| StruqtureError::GenericError {
msg: format!("Invalid semver version: {version}"),
})?;
let patch_version: Vec<&str> = rsplit[2].splitn(2, '-').collect();
let patch_version =
u32::from_str(patch_version[0]).map_err(|_| StruqtureError::GenericError {
msg: format!("Invalid semver version: {version}"),
})?;
Ok((major_version, minor_version, patch_version))
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
#[non_exhaustive]
pub enum StruqtureType {
PauliProduct,
PauliOperator,
PauliHamiltonian,
PauliLindbladNoiseOperator,
PauliLindbladOpenSystem,
PlusMinusOperator,
PlusMinusLindbladNoiseOperator,
PlusMinusProduct,
DecoherenceOperator,
DecoherenceProduct,
FermionOperator,
FermionHamiltonian,
FermionLindbladNoiseOperator,
FermionLindbladOpenSystem,
FermionProduct,
HermitianFermionProduct,
BosonHamiltonian,
BosonOperator,
BosonLindbladNoiseOperator,
BosonLindbladOpenSystem,
HermitianBosonProduct,
BosonProduct,
MixedOperator,
MixedHamiltonian,
MixedLindbladNoiseOperator,
MixedLindbladOpenSystem,
MixedPlusMinusOperator,
MixedDecoherenceProduct,
MixedProduct,
HermitianMixedProduct,
MixedPlusMinusProduct,
}
impl Display for StruqtureType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
StruqtureType::PauliProduct => write!(f, "PauliProduct"),
StruqtureType::PauliOperator => write!(f, "PauliOperator"),
StruqtureType::PauliHamiltonian => write!(f, "PauliHamiltonian"),
StruqtureType::PauliLindbladNoiseOperator => write!(f, "PauliLindbladNoiseOperator"),
StruqtureType::PauliLindbladOpenSystem => write!(f, "PauliLindbladOpenSystem"),
StruqtureType::PlusMinusOperator => write!(f, "PlusMinusOperator"),
StruqtureType::PlusMinusLindbladNoiseOperator => {
write!(f, "PlusMinusLindbladNoiseOperator")
}
StruqtureType::PlusMinusProduct => write!(f, "PlusMinusProduct"),
StruqtureType::DecoherenceOperator => write!(f, "DecoherenceOperator"),
StruqtureType::DecoherenceProduct => write!(f, "DecoherenceProduct"),
StruqtureType::FermionOperator => write!(f, "FermionOperator"),
StruqtureType::FermionHamiltonian => write!(f, "FermionHamiltonian"),
StruqtureType::FermionLindbladNoiseOperator => {
write!(f, "FermionLindbladNoiseOperator")
}
StruqtureType::FermionLindbladOpenSystem => write!(f, "FermionLindbladOpenSystem"),
StruqtureType::FermionProduct => write!(f, "FermionProduct"),
StruqtureType::HermitianFermionProduct => write!(f, "HermitianFermionProduct"),
StruqtureType::BosonHamiltonian => write!(f, "BosonHamiltonian"),
StruqtureType::BosonOperator => write!(f, "BosonOperator"),
StruqtureType::BosonLindbladNoiseOperator => write!(f, "BosonLindbladNoiseOperator"),
StruqtureType::BosonLindbladOpenSystem => write!(f, "BosonLindbladOpenSystem"),
StruqtureType::HermitianBosonProduct => write!(f, "HermitianBosonProduct"),
StruqtureType::BosonProduct => write!(f, "BosonProduct"),
StruqtureType::MixedOperator => write!(f, "MixedOperator"),
StruqtureType::MixedHamiltonian => write!(f, "MixedHamiltonian"),
StruqtureType::MixedLindbladNoiseOperator => write!(f, "MixedLindbladNoiseOperator"),
StruqtureType::MixedLindbladOpenSystem => write!(f, "MixedLindbladOpenSystem"),
StruqtureType::MixedPlusMinusOperator => write!(f, "MixedPlusMinusOperator"),
StruqtureType::MixedDecoherenceProduct => write!(f, "MixedDecoherenceProduct"),
StruqtureType::MixedProduct => write!(f, "MixedProduct"),
StruqtureType::HermitianMixedProduct => write!(f, "HermitianMixedProduct"),
StruqtureType::MixedPlusMinusProduct => write!(f, "MixedPlusMinusProduct"),
}
}
}