Add a richer Rust Card type
    
    
      
        Getty Ritter
        7 years ago
      
    
    
  
  
  | 13 | 13 | |
| 14 | 14 | const SCALE: i32 = 3; | 
| 15 | 15 | |
| 16 | #[derive(Debug)] | |
| 17 | struct Card<'a> { | |
| 18 | name: &'a str, | |
| 19 | icon: String, | |
| 20 | card_type: CardType<'a>, | |
| 21 | } | |
| 22 | ||
| 23 | #[derive(Debug)] | |
| 24 | enum CardType<'a> { | |
| 25 | Monster { | |
| 26 | hp: &'a str, | |
| 27 | melee: Option<&'a str>, | |
| 28 | ranged: Option<&'a str>, | |
| 29 | arcane: Option<&'a str>, | |
| 30 | defense: Option<&'a str>, | |
| 31 | action: &'a str, | |
| 32 | effect: &'a str, | |
| 33 | }, | |
| 34 | Weapon { | |
| 35 | weapon_type: WeaponType, | |
| 36 | ability: &'a str, | |
| 37 | effect: &'a str, | |
| 38 | }, | |
| 39 | Generic { | |
| 40 | kind: Kind, | |
| 41 | effect: &'a str, | |
| 42 | }, | |
| 43 | } | |
| 44 | ||
| 45 | #[derive(Debug)] | |
| 46 | enum Kind { Ability, Equipment, Item, Plant, Treasure } | |
| 47 | ||
| 48 | #[derive(Debug)] | |
| 49 | enum WeaponType { Melee, Ranged, Arcane } | |
| 50 | ||
| 51 | impl<'a> Card<'a> { | |
| 52 | fn from_record(rec: &'a rrecutils::Record) | |
| 53 | -> Result<Card<'a>, failure::Error> | |
| 54 | { | |
| 55 | let name = rec.get("Name")?; | |
| 56 | ||
| 57 | let card_type = match rec.get_type()? { | |
| 58 | "Weapon" => CardType::Weapon { | |
| 59 | weapon_type: match rec.get("Type")? { | |
| 60 | "melee" => WeaponType::Melee, | |
| 61 | "ranged" => WeaponType::Ranged, | |
| 62 | "magic" | "arcane" => WeaponType::Arcane, | |
| 63 | t => bail!("Unknown weapon type: {}", t), | |
| 64 | }, | |
| 65 | ability: rec.get("Ability")?, | |
| 66 | effect: rec.get("Effect")?, | |
| 67 | }, | |
| 68 | "Monster" => CardType::Monster { | |
| 69 | hp: rec.get("HP")?, | |
| 70 | melee: rec.get("Melee").ok(), | |
| 71 | ranged: rec.get("Ranged").ok(), | |
| 72 | arcane: rec.get("Arcane").ok(), | |
| 73 | defense: rec.get("Defense").ok(), | |
| 74 | action: rec.get("Action")?, | |
| 75 | effect: rec.get("Effect")?, | |
| 76 | }, | |
| 77 | t => CardType::Generic { | |
| 78 | kind: match t { | |
| 79 | "Ability" => Kind::Ability, | |
| 80 | "Item" => Kind::Item, | |
| 81 | "Equipment" => Kind::Equipment, | |
| 82 | "Plant" => Kind::Plant, | |
| 83 | "Treasure" => Kind::Treasure, | |
| 84 | _ => bail!("Unknown card type: {}", t), | |
| 85 | }, | |
| 86 | effect: rec.get("Effect")?, | |
| 87 | } | |
| 88 | }; | |
| 89 | ||
| 90 | ||
| 91 | let icon = format!("icon"); | |
| 92 | ||
| 93 | Ok(Card { name, icon, card_type }) | |
| 94 | } | |
| 95 | } | |
| 96 | ||
| 16 | 97 | fn draw_card(rec: &rrecutils::Record) -> Result<(), failure::Error> { | 
| 17 | 98 | let typ = match rec.rec_type { | 
| 18 | 99 | Some(ref t) => t, | 
| 19 | 100 | None => return Ok(()), | 
| 20 | 101 | }; | 
| 21 | let name = rec.get("Name") | |
| 22 | .ok_or(format_err!("Weapon found with no Name!"))?; | |
| 102 | let _ = Card::from_record(rec)?; | |
| 103 | let name = rec.get("Name")?; | |
| 23 | 104 | |
| 24 | 105 | let surf = cairo::ImageSurface::create( | 
| 25 | 106 | cairo::Format::Rgb24, | 
| 52 | 133 | "Weapon" => format!( | 
| 53 | 134 | "{} (Weapon, {})", | 
| 54 | 135 | name, | 
| 55 | rec.get("Type") | |
| 56 | .ok_or(format_err!("Missing Type for {}", name))? | |
| 136 | rec.get("Type")? | |
| 57 | 137 | .to_title_case(), | 
| 58 | 138 | ), | 
| 59 | 139 | "Ability" | "Equipment" | "Item" | "Plant" | "Treasure" => | 
| 60 | 140 | format!("{} ({})", name, typ), | 
| 61 | 141 | "Monster" => { | 
| 62 | 142 | let mut buf = String::new(); | 
| 63 | let hp = rec.get("HP") | |
| 143 | let hp = rec.get("HP")?; | |
| 64 | 144 | buf.push_str(&format!("{} (Beast <span font='8' font_weight='heavy'>HP</span>{}", name, hp)); | 
| 65 | if let | |
| 145 | if let Ok(m) = rec.get("Melee") { | |
| 66 | 146 | buf.push_str(&format!(" <span font='8' font_weight='heavy'>M</span>{}", m)); | 
| 67 | 147 | } | 
| 68 | if let | |
| 148 | if let Ok(m) = rec.get("Ranged") { | |
| 69 | 149 | buf.push_str(&format!(" <span font='8' font_weight='heavy'>R</span>{}", m)); | 
| 70 | 150 | } | 
| 71 | if let | |
| 151 | if let Ok(m) = rec.get("Arcane") { | |
| 72 | 152 | buf.push_str(&format!(" <span font='8' font_weight='heavy'>A</span>{}", m)); | 
| 73 | 153 | } | 
| 74 | if let | |
| 154 | if let Ok(m) = rec.get("Defense") { | |
| 75 | 155 | buf.push_str(&format!(" <span font='8' font_weight='heavy'>D</span>{}", m)); | 
| 76 | 156 | } | 
| 77 | 157 | buf.push_str(")"); | 
| 99 | 179 | match typ.as_ref() { | 
| 100 | 180 | "Weapon" => { | 
| 101 | 181 | buf.push_str("<span font_weight=\"bold\">"); | 
| 102 | buf.push_str(rec.get("Ability") | |
| 103 | .ok_or(format_err!("Missing Ability for {}", name))?); | |
| 182 | buf.push_str(rec.get("Ability")?); | |
| 104 | 183 | buf.push_str(":</span> "); | 
| 105 | buf.push_str(rec.get("Effect") | |
| 106 | .ok_or(format_err!("Missing Effect for {}", name))?); | |
| 184 | buf.push_str(rec.get("Effect")?); | |
| 107 | 185 | } | 
| 108 | 186 | "Ability" | "Equipment" | "Item" | "Plant" | "Treasure" => | 
| 109 | buf.push_str(rec.get("Effect") | |
| 110 | .ok_or(format_err!("Missing Effect for {}", name))?), | |
| 187 | buf.push_str(rec.get("Effect")?), | |
| 111 | 188 | "Monster" => { | 
| 112 | 189 | buf.push_str("<span font_weight=\"bold\">"); | 
| 113 | buf.push_str(rec.get("Action") | |
| 114 | .ok_or(format_err!("Missing Action for {}", name))?); | |
| 190 | buf.push_str(rec.get("Action")?); | |
| 115 | 191 | buf.push_str(":</span> "); | 
| 116 | buf.push_str(rec.get("Effect") | |
| 117 | .ok_or(format_err!("Missing Effect for {}", name))?); | |
| 192 | buf.push_str(rec.get("Effect")?); | |
| 118 | 193 | } | 
| 119 | 194 | _ => bail!("Unknown type: {}", typ), | 
| 120 | 195 | } | 
| 129 | 204 | let icon_path = special_icon.unwrap_or(format!( | 
| 130 | 205 | "../icons/{}-icon.svg", | 
| 131 | 206 | match typ.as_ref() { | 
| 132 | "Weapon" => rec.get("Type") | |
| 133 | .ok_or(format_err!("Missing Type for {}", name))? | |
| 134 |  | |
| 207 | "Weapon" => rec.get("Type")?.to_owned(), | |
| 135 | 208 | _ => typ.to_lowercase(), | 
| 136 | 209 | }, | 
| 137 | 210 | )); |