boseiju/ability_tree/object/
object_kind.rs1mod artifact_subtype;
2mod battle_subtype;
3mod card;
4mod card_type;
5mod creature_subtype;
6mod enchantment_subtype;
7mod instant_sorcery_subtype;
8mod land_subtype;
9mod permanent;
10mod planeswalker_subtype;
11mod spell;
12mod supertype;
13
14pub use artifact_subtype::ArtifactSubtype;
15pub use battle_subtype::BattleSubtype;
16pub use card::CardObjectKind;
17pub use card_type::CardType;
18pub use creature_subtype::CreatureSubtype;
19pub use enchantment_subtype::EnchantmentSubtype;
20pub use instant_sorcery_subtype::SpellSubtype;
21pub use land_subtype::LandSubtype;
22pub use permanent::PermanentObjectKind;
23pub use planeswalker_subtype::PlaneswalkerSubtype;
24pub use spell::SpellObjectKind;
25pub use supertype::Supertype;
26
27use crate::ability_tree::AbilityTreeNode;
28use crate::ability_tree::MAX_CHILDREN_PER_NODE;
29
30#[derive(idris_derive::Idris)]
36#[derive(serde::Serialize, serde::Deserialize)]
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
38pub enum ObjectKind {
39 ArtifactSubtype(ArtifactSubtype),
40 BattleSubtype(BattleSubtype),
41 Card(CardObjectKind),
42 CardType(CardType),
43 CreatureSubtype(CreatureSubtype),
44 EnchantmentSubtype(EnchantmentSubtype),
45 InstantSorcerySubtype(SpellSubtype),
46 LandSubtype(LandSubtype),
47 Permanent(PermanentObjectKind),
48 PlaneswalkerSubtype(PlaneswalkerSubtype),
49 Spell(SpellObjectKind),
50 Supertype(Supertype),
51}
52
53impl ObjectKind {
54 pub fn all() -> impl Iterator<Item = Self> {
55 std::iter::empty()
56 .chain(ArtifactSubtype::all().map(Self::ArtifactSubtype))
57 .chain(BattleSubtype::all().map(Self::BattleSubtype))
58 .chain(CardObjectKind::all().map(Self::Card))
59 .chain(CardType::all().map(Self::CardType))
60 .chain(CreatureSubtype::all().map(Self::CreatureSubtype))
61 .chain(EnchantmentSubtype::all().map(Self::EnchantmentSubtype))
62 .chain(SpellSubtype::all().map(Self::InstantSorcerySubtype))
63 .chain(LandSubtype::all().map(Self::LandSubtype))
64 .chain(PermanentObjectKind::all().map(Self::Permanent))
65 .chain(PlaneswalkerSubtype::all().map(Self::PlaneswalkerSubtype))
66 .chain(SpellObjectKind::all().map(Self::Spell))
67 .chain(Supertype::all().map(Self::Supertype))
68 }
69}
70
71impl AbilityTreeNode for ObjectKind {
72 fn node_id(&self) -> usize {
73 use crate::ability_tree::tree_node::MtgDataNodeKind;
74 use idris::Idris;
75
76 crate::ability_tree::NodeKind::MtgData(MtgDataNodeKind::ObjectKindIdMarker).id()
77 }
78
79 fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
80 let mut children = arrayvec::ArrayVec::new_const();
81 match self {
82 Self::ArtifactSubtype(child) => children.push(child as &dyn AbilityTreeNode),
83 Self::BattleSubtype(child) => children.push(child as &dyn AbilityTreeNode),
84 Self::Card(child) => children.push(child as &dyn AbilityTreeNode),
85 Self::CardType(child) => children.push(child as &dyn AbilityTreeNode),
86 Self::CreatureSubtype(child) => children.push(child as &dyn AbilityTreeNode),
87 Self::EnchantmentSubtype(child) => children.push(child as &dyn AbilityTreeNode),
88 Self::InstantSorcerySubtype(child) => children.push(child as &dyn AbilityTreeNode),
89 Self::LandSubtype(child) => children.push(child as &dyn AbilityTreeNode),
90 Self::Permanent(child) => children.push(child as &dyn AbilityTreeNode),
91 Self::PlaneswalkerSubtype(child) => children.push(child as &dyn AbilityTreeNode),
92 Self::Spell(child) => children.push(child as &dyn AbilityTreeNode),
93 Self::Supertype(child) => children.push(child as &dyn AbilityTreeNode),
94 }
95 children
96 }
97
98 fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
99 use std::io::Write;
100 write!(out, "object kind")?;
101 out.push_final_branch()?;
102 match self {
103 Self::ArtifactSubtype(child) => child.display(out)?,
104 Self::BattleSubtype(child) => child.display(out)?,
105 Self::Card(child) => child.display(out)?,
106 Self::CardType(child) => child.display(out)?,
107 Self::CreatureSubtype(child) => child.display(out)?,
108 Self::EnchantmentSubtype(child) => child.display(out)?,
109 Self::InstantSorcerySubtype(child) => child.display(out)?,
110 Self::LandSubtype(child) => child.display(out)?,
111 Self::Permanent(child) => child.display(out)?,
112 Self::PlaneswalkerSubtype(child) => child.display(out)?,
113 Self::Spell(child) => child.display(out)?,
114 Self::Supertype(child) => child.display(out)?,
115 }
116 out.pop_branch();
117 Ok(())
118 }
119
120 fn node_tag(&self) -> &'static str {
121 "object kind"
122 }
123
124 #[cfg(feature = "spanned_tree")]
125 fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
126 match self {
127 Self::ArtifactSubtype(child) => child.node_span(),
128 Self::BattleSubtype(child) => child.node_span(),
129 Self::Card(child) => child.node_span(),
130 Self::CardType(child) => child.node_span(),
131 Self::CreatureSubtype(child) => child.node_span(),
132 Self::EnchantmentSubtype(child) => child.node_span(),
133 Self::InstantSorcerySubtype(child) => child.node_span(),
134 Self::LandSubtype(child) => child.node_span(),
135 Self::Permanent(child) => child.node_span(),
136 Self::PlaneswalkerSubtype(child) => child.node_span(),
137 Self::Spell(child) => child.node_span(),
138 Self::Supertype(child) => child.node_span(),
139 }
140 }
141}
142
143#[cfg(feature = "lexer")]
144impl crate::lexer::IntoToken for ObjectKind {
145 fn try_from_span(span: &crate::lexer::Span) -> Option<Self> {
146 if let Some(result) = ArtifactSubtype::try_from_span(span) {
147 Some(Self::ArtifactSubtype(result))
148 } else if let Some(result) = BattleSubtype::try_from_span(span) {
149 Some(Self::BattleSubtype(result))
150 } else if let Some(result) = CardObjectKind::try_from_span(span) {
151 Some(Self::Card(result))
152 } else if let Some(result) = CardType::try_from_span(span) {
153 Some(Self::CardType(result))
154 } else if let Some(result) = CreatureSubtype::try_from_span(span) {
155 Some(Self::CreatureSubtype(result))
156 } else if let Some(result) = EnchantmentSubtype::try_from_span(span) {
157 Some(Self::EnchantmentSubtype(result))
158 } else if let Some(result) = SpellSubtype::try_from_span(span) {
159 Some(Self::InstantSorcerySubtype(result))
160 } else if let Some(result) = LandSubtype::try_from_span(span) {
161 Some(Self::LandSubtype(result))
162 } else if let Some(result) = PermanentObjectKind::try_from_span(span) {
163 Some(Self::Permanent(result))
164 } else if let Some(result) = PlaneswalkerSubtype::try_from_span(span) {
165 Some(Self::PlaneswalkerSubtype(result))
166 } else if let Some(result) = SpellObjectKind::try_from_span(span) {
167 Some(Self::Spell(result))
168 } else if let Some(result) = Supertype::try_from_span(span) {
169 Some(Self::Supertype(result))
170 } else {
171 None
172 }
173 }
174}
175
176#[cfg(feature = "parser")]
177impl crate::utils::DummyInit for ObjectKind {
178 fn dummy_init() -> Self {
179 Self::Card(crate::utils::dummy())
180 }
181}