use std::borrow::Cow;
use super::dataflow::DataflowOpTrait;
use super::{impl_op_name, OpTag};
use crate::types::{EdgeKind, Signature, Type, TypeRow};
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[non_exhaustive]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct Tag {
pub tag: usize,
pub variants: Vec<TypeRow>,
}
impl Tag {
pub fn new(tag: usize, variants: Vec<TypeRow>) -> Self {
Self { tag, variants }
}
}
impl_op_name!(Tag);
impl DataflowOpTrait for Tag {
const TAG: OpTag = OpTag::Leaf;
fn description(&self) -> &str {
"Tag Sum operation"
}
fn signature(&self) -> Cow<'_, Signature> {
Cow::Owned(Signature::new(
self.variants
.get(self.tag)
.expect("Not a valid tag")
.clone(),
vec![Type::new_sum(self.variants.clone())],
))
}
fn other_input(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
fn other_output(&self) -> Option<EdgeKind> {
Some(EdgeKind::StateOrder)
}
fn substitute(&self, subst: &crate::types::Substitution) -> Self {
Self {
variants: self.variants.iter().map(|r| r.substitute(subst)).collect(),
tag: self.tag,
}
}
}