1use std::borrow::Cow;
4
5use super::dataflow::DataflowOpTrait;
6use super::{OpTag, impl_op_name};
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 #[must_use]
25 pub fn new(tag: usize, variants: Vec<TypeRow>) -> Self {
26 Self { tag, variants }
27 }
28}
29
30impl_op_name!(Tag);
31
32impl DataflowOpTrait for Tag {
33 const TAG: OpTag = OpTag::Leaf;
34
35 fn description(&self) -> &'static str {
37 "Tag Sum operation"
38 }
39
40 fn signature(&self) -> Cow<'_, Signature> {
42 Cow::Owned(Signature::new(
44 self.variants
45 .get(self.tag)
46 .expect("Not a valid tag")
47 .clone(),
48 vec![Type::new_sum(self.variants.clone())],
49 ))
50 }
51
52 fn other_input(&self) -> Option<EdgeKind> {
53 Some(EdgeKind::StateOrder)
54 }
55
56 fn other_output(&self) -> Option<EdgeKind> {
57 Some(EdgeKind::StateOrder)
58 }
59
60 fn substitute(&self, subst: &crate::types::Substitution) -> Self {
61 Self {
62 variants: self.variants.iter().map(|r| r.substitute(subst)).collect(),
63 tag: self.tag,
64 }
65 }
66}