2022-11-11 15:00:07 +01:00
use crossterm ::terminal ::enable_raw_mode ;
2022-10-05 17:57:01 +02:00
use serde ::Deserialize ;
2022-11-11 15:00:07 +01:00
use std ::{ io , iter , time ::Duration } ;
use tui ::{
backend ::CrosstermBackend ,
layout ,
style ::{ Color , Style } ,
text ::Text ,
widgets ::{ Block , Borders , List , ListItem , Paragraph , Widget } ,
2022-10-05 17:57:01 +02:00
} ;
2022-11-11 15:00:07 +01:00
type Terminal = tui ::Terminal < CrosstermBackend < io ::Stdout > > ;
fn main ( ) -> Result < ( ) , Box < dyn std ::error ::Error > > {
let stdout = io ::stdout ( ) ;
enable_raw_mode ( ) ? ;
let mut backend = CrosstermBackend ::new ( stdout ) ;
let mut terminal = Terminal ::new ( backend ) ? ;
terminal . hide_cursor ( ) ? ;
terminal . clear ( ) ? ;
let all_cards = vec! [
2022-10-05 17:57:01 +02:00
Card ::SpellCard {
name : " The Cheerful Coffin " . to_owned ( ) ,
text : " Discard up to 3 Monster Cards from your hand to the Graveyard. " . to_owned ( )
} ,
Card ::EffectMonster {
name : " Des Lacooda " . to_owned ( ) ,
effect : " 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 : 500 ,
def : 600 ,
level : 3 ,
r#type : " Zombie " . to_owned ( ) ,
attribute : " EARTH " . to_owned ( ) ,
}
2022-11-11 15:00:07 +01:00
] ;
let mut cards = all_cards . clone ( ) ;
let mut search_text = String ::new ( ) ;
2022-10-05 17:57:01 +02:00
2022-11-11 15:00:07 +01:00
loop {
refresh ( & mut terminal , & cards , & search_text ) ;
2022-10-05 17:57:01 +02:00
}
2022-11-11 15:00:07 +01:00
Ok ( ( ) )
2022-10-05 17:57:01 +02:00
}
2022-11-11 15:00:07 +01:00
fn refresh ( term : & mut Terminal , cards : & Vec < Card > , search_text : & str ) -> Result < ( ) , io ::Error > {
let mut list = selectable_list (
search_text ,
cards
. iter ( )
. map ( | c | ListItem ::new ( format! ( " {c:?} " ) ) )
. collect ::< Vec < _ > > ( ) ,
None ,
) ;
term . draw ( | mut frame | {
frame . render_widget ( list , frame . size ( ) ) ;
} ) ? ;
Ok ( ( ) )
2022-10-05 17:57:01 +02:00
}
2022-11-11 15:00:07 +01:00
pub fn selectable_list < ' a > (
title : & ' a str ,
content : Vec < ListItem < ' a > > ,
selected : Option < usize > ,
) -> List < ' a > {
List ::new ( content )
. block (
Block ::default ( )
. title ( title )
. borders ( Borders ::TOP | Borders ::RIGHT | Borders ::LEFT ) ,
)
. highlight_style ( Style ::default ( ) . fg ( Color ::LightGreen ) )
. highlight_symbol ( " > " )
2022-10-05 17:57:01 +02:00
}
2022-11-11 15:00:07 +01:00
#[ derive(Debug, Deserialize, PartialEq, Eq, Clone) ]
2022-10-05 17:57:01 +02:00
#[ serde(tag = " type " ) ]
enum Card {
#[ serde(rename = " Spell Card " ) ]
SpellCard {
name : String ,
#[ serde(rename = " desc " ) ]
text : String ,
} ,
#[ serde(
rename = " Effect Monster " ,
alias = " Flip Effect Monster " ,
alias = " Union Effect Monster "
) ]
EffectMonster {
name : String ,
#[ serde(rename = " desc " ) ]
effect : String ,
atk : i32 ,
def : i32 ,
level : i32 ,
attribute : String ,
#[ serde(rename = " race " ) ]
r#type : String ,
} ,
}
#[ test ]
fn test_spell ( ) {
let s = 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 "
} " #;
let coffin : Card = serde_json ::from_str ( s ) . unwrap ( ) ;
assert_eq! (
coffin ,
Card ::SpellCard {
name : " The Cheerful Coffin " . to_owned ( ) ,
text : " Discard up to 3 Monster Cards from your hand to the Graveyard. " . to_owned ( )
}
)
}
#[ test ]
fn test_monster ( ) {
let s = 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 "
} " #;
let munch : Card = serde_json ::from_str ( s ) . unwrap ( ) ;
assert_eq! (
munch ,
Card ::EffectMonster {
name : " Des Lacooda " . to_owned ( ) ,
effect : " 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 : 500 ,
def : 600 ,
level : 3 ,
r#type : " Zombie " . to_owned ( ) ,
attribute : " EARTH " . to_owned ( ) ,
}
)
}