boseiju/ability_tree/card_layout/
token_layout.rs1use crate::ability_tree::AbilityTreeNode;
2use crate::ability_tree::MAX_CHILDREN_PER_NODE;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
6#[derive(serde::Serialize, serde::Deserialize)]
7pub struct TokenLayout {
8 pub name: String,
9 pub card_type: crate::ability_tree::type_line::TypeLine,
10 pub colors: crate::ability_tree::colors::Colors,
11 pub abilities: crate::AbilityTree,
12 #[cfg(feature = "spanned_tree")]
13 pub span: crate::ability_tree::span::TreeSpan,
14}
15
16impl AbilityTreeNode for TokenLayout {
17 fn node_id(&self) -> usize {
18 use idris::Idris;
19 crate::ability_tree::NodeKind::TokenLayout.id()
20 }
21
22 fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
23 let mut children = arrayvec::ArrayVec::new_const();
24 children.push(&self.card_type as &dyn AbilityTreeNode);
25 children.push(&self.colors as &dyn AbilityTreeNode);
26 children.push(&self.abilities as &dyn AbilityTreeNode);
27 children
28 }
29
30 fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
31 use std::io::Write;
32 write!(out, "token:")?;
33 out.push_inter_branch()?;
34 write!(out, "types:")?;
35 out.push_final_branch()?;
36 self.card_type.display(out)?;
37 out.pop_branch();
38 out.next_inter_branch()?;
39 write!(out, "color:")?;
40 out.push_final_branch()?;
41 self.colors.display(out)?;
42 out.pop_branch();
43 out.next_final_branch()?;
44 write!(out, "abilities:")?;
45 out.push_final_branch()?;
46 self.abilities.display(out)?;
47 out.pop_branch();
48 out.pop_branch();
49 Ok(())
50 }
51
52 fn node_tag(&self) -> &'static str {
53 "token description"
54 }
55
56 #[cfg(feature = "spanned_tree")]
57 fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
58 self.span
59 }
60}
61
62impl super::LayoutImpl for TokenLayout {
63 fn card_types(&self) -> arrayvec::ArrayVec<mtg_data::CardType, 4> {
64 self.card_type.card_types()
65 }
66
67 fn mana_value(&self) -> usize {
68 0
69 }
70
71 #[cfg(feature = "parser")]
72 fn from_raw_card(raw_card: &mtg_cardbase::Card) -> Result<Self, String> {
73 use crate::lexer::IntoToken;
74
75 let type_line_span = crate::lexer::Span {
76 start: 0,
77 length: raw_card.type_line.len(),
78 text: raw_card.type_line.as_str(),
79 };
80
81 Ok(TokenLayout {
82 name: raw_card.name.clone(),
83 card_type: crate::ability_tree::type_line::TypeLine::try_from_span(&type_line_span)
84 .ok_or_else(|| format!("Failed to parse card type: {}", raw_card.type_line))?,
85 colors: crate::ability_tree::colors::Colors::try_from(raw_card.color_identity.as_slice())?,
86 abilities: match raw_card.oracle_text.as_ref() {
87 Some(oracle_text) => crate::AbilityTree::from_oracle_text(oracle_text, &raw_card.name)
88 .map_err(|e| format!("Failed to parse oracle text to ability tree: {e}"))?,
89 None => crate::AbilityTree::empty(),
90 },
91 #[cfg(feature = "spanned_tree")]
92 span: Default::default(),
93 })
94 }
95
96 fn layout_debug_display<W: std::io::Write>(&self, _output: &mut W) -> std::io::Result<()> {
97 unimplemented!()
98 }
99}
100
101#[cfg(feature = "parser")]
102impl crate::utils::DummyInit for TokenLayout {
103 fn dummy_init() -> Self {
104 Self {
105 name: String::with_capacity(0),
106 card_type: crate::utils::dummy(),
107 abilities: crate::utils::dummy(),
108 colors: crate::utils::dummy(),
109 #[cfg(feature = "spanned_tree")]
110 span: Default::default(),
111 }
112 }
113}