2023-01-26 23:07:16 +01:00
use serde ::Deserialize ;
use std ::fmt ::{ self , Display } ;
#[ derive(Debug, Deserialize, PartialEq, Eq, Clone) ]
pub struct CardInfo {
pub data : Vec < Card > ,
}
#[ derive(Debug, Deserialize, PartialEq, Eq, Clone, Default) ]
pub struct Card {
pub id : usize ,
#[ serde(rename = " type " ) ]
pub card_type : String ,
pub name : String ,
#[ serde(rename = " desc " ) ]
pub text : String ,
// Will also be None for ?
pub atk : Option < i32 > ,
pub def : Option < i32 > ,
pub attribute : Option < String > ,
#[ serde(rename = " race " ) ]
pub r#type : String ,
// also includes rank
pub level : Option < i32 > ,
#[ serde(rename = " linkval " ) ]
pub link_rating : Option < i32 > ,
#[ serde(rename = " linkmarkers " ) ]
pub link_arrows : Option < Vec < String > > ,
}
impl Display for Card {
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
2023-01-30 17:27:44 +01:00
write! ( f , r # "<h2><a href="/card/{}">{}</a></h2><br/><em>"# , & self . id , & self . name ) ? ;
2023-01-26 23:07:16 +01:00
if let Some ( level ) = self . level {
2023-01-30 11:39:42 +01:00
if self . card_type . contains ( " XYZ " ) {
f . write_str ( " Rank " ) ? ;
} else {
f . write_str ( " Level " ) ? ;
}
write! ( f , " {level} " ) ? ;
2023-01-26 23:07:16 +01:00
} else if let Some ( lr ) = self . link_rating {
write! ( f , " Link {lr} " ) ? ;
}
if let Some ( attr ) = & self . attribute {
write! ( f , " {attr}/ " ) ? ;
}
2023-01-30 15:57:08 +01:00
write! ( f , " {} {} " , self . r#type , self . card_type ) ? ;
2023-01-26 23:07:16 +01:00
if self . card_type . contains ( & String ::from ( " Monster " ) ) {
2023-01-27 14:18:33 +01:00
f . write_str ( " <br/> " ) ? ;
2023-01-26 23:07:16 +01:00
match ( self . atk , self . def ) {
2023-01-27 00:03:00 +01:00
( Some ( atk ) , Some ( def ) ) = > write! ( f , " {atk} ATK / {def} DEF " ) ? ,
2023-01-26 23:07:16 +01:00
( Some ( atk ) , None ) if self . link_rating . is_some ( ) = > write! ( f , " {atk} ATK " ) ? ,
2023-01-27 00:03:00 +01:00
( None , Some ( def ) ) = > write! ( f , " ? ATK / {def} DEF " ) ? ,
( Some ( atk ) , None ) = > write! ( f , " {atk} ATK / ? DEF " ) ? ,
( None , None ) = > write! ( f , " ? ATK / ? DEF " ) ? ,
2023-01-26 23:07:16 +01:00
}
}
2023-01-30 15:57:08 +01:00
f . write_str ( " </em><br/> " ) ? ;
f . write_str ( & self . text ) ? ;
2023-01-26 23:07:16 +01:00
Ok ( ( ) )
}
}
#[ cfg(test) ]
pub mod tests {
use super ::* ;
pub const RAW_SPELL : & str = r #"
{
" id " : 41142615 ,
" name " : " The Cheerful Coffin " ,
" type " : " Spell Card " ,
" desc " : " Discard up to 3 Monster Cards from your hand to the Graveyard. " ,
" race " : " Normal "
} " #;
pub const RAW_MONSTER : & str = r #"
{
" id " : 2326738 ,
" name " : " Des Lacooda " ,
" type " : " Effect Monster " ,
" desc " : " Once per turn: You can change this card to face-down Defense Position. When this card is Flip Summoned: Draw 1 card. " ,
" atk " : 500 ,
" def " : 600 ,
" level " : 3 ,
" race " : " Zombie " ,
" attribute " : " EARTH "
} " #;
#[ test ]
fn test_spell ( ) {
let coffin : Card = serde_json ::from_str ( RAW_SPELL ) . unwrap ( ) ;
assert_eq! (
coffin ,
Card {
id : 41142615 ,
card_type : " Spell Card " . to_owned ( ) ,
name : " The Cheerful Coffin " . to_owned ( ) ,
text : " Discard up to 3 Monster Cards from your hand to the Graveyard. " . to_owned ( ) ,
r#type : " Normal " . to_owned ( ) ,
.. Default ::default ( )
}
)
}
#[ test ]
fn test_monster ( ) {
let munch : Card = serde_json ::from_str ( RAW_MONSTER ) . unwrap ( ) ;
assert_eq! (
munch ,
Card {
id : 2326738 ,
card_type : " Effect Monster " . to_owned ( ) ,
name : " Des Lacooda " . to_owned ( ) ,
text :
" Once per turn: You can change this card to face-down Defense Position. When this card is Flip Summoned: Draw 1 card. "
. to_owned ( ) ,
atk : Some ( 500 ) ,
def : Some ( 600 ) ,
level : Some ( 3 ) ,
r#type : " Zombie " . to_owned ( ) ,
attribute : Some ( " EARTH " . to_owned ( ) ) ,
.. Default ::default ( )
} ,
)
}
}