boseiju/card/
layout.rs

1use crate::ability_tree::card_layout::*;
2
3/// All the layouts of Magic: The Gathering for playable cards.
4#[derive(idris_derive::Idris)]
5#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
6pub enum Layout {
7    Normal { layout: NormalLayout },
8    Split {},
9    Flip {},
10    Transform {},
11    ModalDfc {},
12    Meld {},
13    Leveler {},
14    Class {},
15    Case {},
16    Saga { layout: SagaLayout },
17    Adventure {},
18    Mutate {},
19    Prototype {},
20    Battle {},
21    Planar {},
22    Scheme {},
23    Vanguard {},
24    Token { layout: TokenLayout },
25    DoubleFaced {},
26    Emblem {},
27}
28
29impl Layout {
30    pub fn display<W: std::io::Write>(&self, output: &mut W) -> std::io::Result<()> {
31        match self {
32            Layout::Normal { layout } => layout.layout_debug_display(output),
33            _ => writeln!(output, "Unimplemented!"),
34        }
35    }
36
37    pub fn mana_value(&self) -> usize {
38        match self {
39            Self::Normal { layout } => layout.mana_value(),
40            Self::Split {} => 0,
41            Self::Flip {} => 0,
42            Self::Transform {} => 0,
43            Self::ModalDfc {} => 0,
44            Self::Meld {} => 0,
45            Self::Leveler {} => 0,
46            Self::Class {} => 0,
47            Self::Case {} => 0,
48            Self::Saga { layout } => layout.mana_value(),
49            Self::Adventure {} => 0,
50            Self::Mutate {} => 0,
51            Self::Prototype {} => 0,
52            Self::Battle {} => 0,
53            Self::Planar {} => 0,
54            Self::Scheme {} => 0,
55            Self::Vanguard {} => 0,
56            Self::Token { layout } => layout.mana_value(),
57            Self::DoubleFaced {} => 0,
58            Self::Emblem {} => 0,
59        }
60    }
61
62    pub fn card_types(&self) -> arrayvec::ArrayVec<mtg_data::CardType, 4> {
63        match self {
64            Self::Normal { layout } => layout.card_types(),
65            Self::Split {} => arrayvec::ArrayVec::new_const(),
66            Self::Flip {} => arrayvec::ArrayVec::new_const(),
67            Self::Transform {} => arrayvec::ArrayVec::new_const(),
68            Self::ModalDfc {} => arrayvec::ArrayVec::new_const(),
69            Self::Meld {} => arrayvec::ArrayVec::new_const(),
70            Self::Leveler {} => arrayvec::ArrayVec::new_const(),
71            Self::Class {} => arrayvec::ArrayVec::new_const(),
72            Self::Case {} => arrayvec::ArrayVec::new_const(),
73            Self::Saga { layout } => layout.card_types(),
74            Self::Adventure {} => arrayvec::ArrayVec::new_const(),
75            Self::Mutate {} => arrayvec::ArrayVec::new_const(),
76            Self::Prototype {} => arrayvec::ArrayVec::new_const(),
77            Self::Battle {} => arrayvec::ArrayVec::new_const(),
78            Self::Planar {} => arrayvec::ArrayVec::new_const(),
79            Self::Scheme {} => arrayvec::ArrayVec::new_const(),
80            Self::Vanguard {} => arrayvec::ArrayVec::new_const(),
81            Self::Token { layout } => layout.card_types(),
82            Self::DoubleFaced {} => arrayvec::ArrayVec::new_const(),
83            Self::Emblem {} => arrayvec::ArrayVec::new_const(),
84        }
85    }
86}
87
88#[cfg(feature = "parser")]
89impl TryFrom<&mtg_cardbase::Card> for Layout {
90    type Error = String; // Fixme!
91    fn try_from(raw_card: &mtg_cardbase::Card) -> Result<Self, Self::Error> {
92        match raw_card.layout.as_str() {
93            "normal" => Ok(Layout::Normal {
94                layout: NormalLayout::from_raw_card(raw_card)?,
95            }),
96            "token" => Ok(Self::Token {
97                layout: TokenLayout::from_raw_card(raw_card)?,
98            }),
99            "saga" => Ok(Self::Saga {
100                layout: SagaLayout::from_raw_card(raw_card)?,
101            }),
102            other => Err(format!("Invalid layout in card: {other}")),
103        }
104    }
105}