1use std::borrow::Cow;
4
5use super::dataflow::DataflowOpTrait;
6use super::{impl_op_name, OpTag};
7use crate::types::{EdgeKind, Signature, Type, TypeRow};
8
9#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
11#[non_exhaustive]
12#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
13pub struct Tag {
14 pub tag: usize,
16 pub variants: Vec<TypeRow>,
20}
21
22impl Tag {
23 pub fn new(tag: usize, variants: Vec<TypeRow>) -> Self {
25 Self { tag, variants }
26 }
27}
28
29impl_op_name!(Tag);
30
31impl DataflowOpTrait for Tag {
32 const TAG: OpTag = OpTag::Leaf;
33
34 fn description(&self) -> &str {
36 "Tag Sum operation"
37 }
38
39 fn signature(&self) -> Cow<'_, Signature> {
41 Cow::Owned(Signature::new(
43 self.variants
44 .get(self.tag)
45 .expect("Not a valid tag")
46 .clone(),
47 vec![Type::new_sum(self.variants.clone())],
48 ))
49 }
50
51 fn other_input(&self) -> Option<EdgeKind> {
52 Some(EdgeKind::StateOrder)
53 }
54
55 fn other_output(&self) -> Option<EdgeKind> {
56 Some(EdgeKind::StateOrder)
57 }
58
59 fn substitute(&self, subst: &crate::types::Substitution) -> Self {
60 Self {
61 variants: self.variants.iter().map(|r| r.substitute(subst)).collect(),
62 tag: self.tag,
63 }
64 }
65}