boseiju/
card.rs

1pub mod layout;
2pub mod legalities;
3
4/// A parsed card.
5///
6/// This is the main data type used and passed around.
7#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
8pub struct Card {
9    pub name: String,
10    pub scryfall_id: uuid::Uuid,
11    pub legalities: legalities::Legalities,
12    pub color_identity: crate::ability_tree::colors::Colors,
13    pub layout: layout::Layout,
14    pub images_uris: Option<mtg_cardbase::ImageUris>,
15}
16
17impl Card {
18    pub fn display<W: std::io::Write>(&self, output: &mut W) -> std::io::Result<()> {
19        writeln!(output, "╭──── {} ────", self.name)?;
20        writeln!(output, "│ scryfall id: {}", self.scryfall_id)?;
21        writeln!(output, "│ legalities:")?;
22        self.legalities.display(output)?;
23        writeln!(output, "│ color identity: {}", self.color_identity)?;
24        writeln!(output, "│ layout: ")?;
25        self.layout.display(output)?;
26        writeln!(output, "╰────")?;
27        Ok(())
28    }
29
30    pub fn card_types(&self) -> arrayvec::ArrayVec<mtg_data::CardType, 4> {
31        self.layout.card_types()
32    }
33
34    pub fn mana_value(&self) -> usize {
35        self.layout.mana_value()
36    }
37}
38
39#[cfg(feature = "parser")]
40impl TryFrom<&mtg_cardbase::Card> for Card {
41    type Error = String; // Fixme: proper error handling accross everything
42    fn try_from(raw_card: &mtg_cardbase::Card) -> Result<Self, Self::Error> {
43        use std::str::FromStr;
44        Ok(Card {
45            name: raw_card.name.to_string(),
46            scryfall_id: uuid::Uuid::from_str(&raw_card.id)
47                .map_err(|e| format!("in {}, failed to parse scryfall id to uuid: {e}", raw_card.name))?,
48            legalities: legalities::Legalities::try_from(&raw_card.legalities)
49                .map_err(|e| format!("in {}, failed to parse legalities: {e}", raw_card.name))?,
50            color_identity: crate::ability_tree::colors::Colors::try_from(raw_card.color_identity.as_slice())
51                .map_err(|e| format!("in {}, failed to parse color identity: {e}", raw_card.name))?,
52            layout: layout::Layout::try_from(raw_card)
53                .map_err(|e| format!("in {}, failed to parse layout: {e}", raw_card.name))?,
54            images_uris: raw_card.image_uris.clone(),
55        })
56    }
57}
58
59impl std::fmt::Display for Card {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        let mut buffer = Vec::new();
62        self.display(&mut buffer).map_err(|_| std::fmt::Error)?;
63        let s = std::str::from_utf8(&buffer).map_err(|_| std::fmt::Error)?;
64        write!(f, "{}", s)
65    }
66}