use panproto_schema::Schema;
use serde::{Deserialize, Serialize};
use crate::error::RestrictError;
use crate::functor::FInstance;
use crate::ginstance::GInstance;
use crate::wtype::{CompiledMigration, WInstance};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Instance {
WType(WInstance),
Functor(FInstance),
Graph(GInstance),
}
impl Instance {
#[must_use]
pub const fn shape_name(&self) -> &'static str {
match self {
Self::WType(_) => "wtype",
Self::Functor(_) => "functor",
Self::Graph(_) => "graph",
}
}
pub fn restrict(
&self,
src_schema: &Schema,
tgt_schema: &Schema,
migration: &CompiledMigration,
) -> Result<Self, RestrictError> {
match self {
Self::WType(w) => {
let restricted = crate::wtype_restrict(w, src_schema, tgt_schema, migration)?;
Ok(Self::WType(restricted))
}
Self::Functor(f) => {
let restricted = crate::functor_restrict(f, migration)?;
Ok(Self::Functor(restricted))
}
Self::Graph(g) => {
let restricted = crate::ginstance::graph_restrict(g, migration)?;
Ok(Self::Graph(restricted))
}
}
}
#[must_use]
pub fn element_count(&self) -> usize {
match self {
Self::WType(w) => w.node_count(),
Self::Functor(f) => f.table_count(),
Self::Graph(g) => g.node_count(),
}
}
#[must_use]
pub const fn as_wtype(&self) -> Option<&WInstance> {
match self {
Self::WType(w) => Some(w),
_ => None,
}
}
#[must_use]
pub const fn as_functor(&self) -> Option<&FInstance> {
match self {
Self::Functor(f) => Some(f),
_ => None,
}
}
#[must_use]
pub const fn as_graph(&self) -> Option<&GInstance> {
match self {
Self::Graph(g) => Some(g),
_ => None,
}
}
}
impl From<WInstance> for Instance {
fn from(w: WInstance) -> Self {
Self::WType(w)
}
}
impl From<FInstance> for Instance {
fn from(f: FInstance) -> Self {
Self::Functor(f)
}
}
impl From<GInstance> for Instance {
fn from(g: GInstance) -> Self {
Self::Graph(g)
}
}