11use clap:: ArgMatches ;
22use isahc:: { HttpClient , ReadResponseExt , Request } ;
3-
3+ use serde :: { Deserialize , Serialize } ;
44use serde_json:: { Map , Value } ;
5+ use std:: fmt;
6+ use std:: io:: prelude:: * ;
57
68use crate :: api:: APIError ;
79use crate :: api:: API ;
810
11+ #[ derive( Debug , Deserialize ) ]
12+ struct Drinks {
13+ machines : Vec < Machine > ,
14+ }
15+
16+ #[ derive( Debug , Deserialize ) ]
17+ struct Machine {
18+ name : String ,
19+ display_name : String ,
20+ slots : Vec < Slot > ,
21+ }
22+
23+ impl fmt:: Display for Machine {
24+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
25+ write ! (
26+ f,
27+ "{} ({})\n {}" ,
28+ self . display_name,
29+ self . name,
30+ "=" . repeat( self . display_name. len( ) + self . name. len( ) + 3 )
31+ )
32+ }
33+ }
34+
35+ #[ derive( Debug , Deserialize ) ]
36+ struct Slot {
37+ item : Item ,
38+ number : u64 ,
39+ empty : bool ,
40+ active : bool ,
41+ count : Option < u16 > ,
42+ }
43+
44+ impl fmt:: Display for Slot {
45+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
46+ write ! (
47+ f,
48+ "{}. {}{}" ,
49+ self . number,
50+ self . item,
51+ match self . empty {
52+ true => " [EMPTY]" ,
53+ false => "" ,
54+ }
55+ )
56+ }
57+ }
58+
59+ #[ derive( Debug , Deserialize ) ]
60+ struct Item {
61+ name : String ,
62+ price : u64 ,
63+ }
64+
65+ impl fmt:: Display for Item {
66+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
67+ write ! ( f, "{} ({} Credits)" , self . name, self . price)
68+ }
69+ }
70+
971pub fn list ( matches : & ArgMatches , api : & mut API ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
1072 let token = api. get_token ( ) ?;
1173
74+ let mut term = term:: stdout ( ) . unwrap ( ) ;
75+
1276 let client = HttpClient :: new ( ) ?;
1377 let mut url = "https://drink.csh.rit.edu/drinks" . to_string ( ) ;
1478 if let Some ( machine) = matches. value_of ( "machine" ) {
@@ -17,61 +81,28 @@ pub fn list(matches: &ArgMatches, api: &mut API) -> Result<(), Box<dyn std::erro
1781 }
1882 let request = Request :: get ( url) . header ( "Authorization" , token) . body ( ( ) ) ?;
1983
20- let drinks: Value = client. send ( request) ?. json ( ) ?;
21- let drinks: & Map < String , Value > = match drinks. as_object ( ) {
22- Some ( drinks) => drinks,
23- None => panic ! ( "Fuck" ) ,
24- } ;
25- let machines: & Vec < Value > = match drinks. get ( "machines" ) {
26- Some ( machines) => match machines. as_array ( ) {
27- Some ( machines) => machines,
28- None => return Err ( Box :: new ( APIError :: BadFormat ) ) ,
29- } ,
30- None => {
31- eprintln ! ( "Couldn't fetch machines! {:?}" , drinks) ;
32- return Err ( Box :: new ( APIError :: BadFormat ) ) ;
33- }
34- } ;
35- for machine in machines {
36- let machine: & Map < String , Value > = match machine. as_object ( ) {
37- Some ( machine) => machine,
38- None => panic ! ( "Fuck!" ) ,
39- } ;
40- let display_name = match machine[ "display_name" ] . as_str ( ) {
41- Some ( name) => name. to_string ( ) ,
42- None => return Err ( Box :: new ( APIError :: BadFormat ) ) ,
43- } ;
44- let name = match machine[ "name" ] . as_str ( ) {
45- Some ( name) => name. to_string ( ) ,
46- None => return Err ( Box :: new ( APIError :: BadFormat ) ) ,
47- } ;
48- let subject_line = format ! ( "{} ({})" , display_name, name) ;
49- println ! ( "{}" , & subject_line) ;
50- println ! ( "{}" , "=" . repeat( subject_line. len( ) ) ) ;
51- let slots: & Vec < Value > = match machine[ "slots" ] . as_array ( ) {
52- Some ( slots) => slots,
53- None => return Err ( Box :: new ( APIError :: BadFormat ) ) ,
54- } ;
55- for slot in slots {
56- let slot: & Map < String , Value > = match slot. as_object ( ) {
57- Some ( slot) => slot,
58- None => return Err ( Box :: new ( APIError :: BadFormat ) ) ,
59- } ;
60-
61- let item: & Map < String , Value > = match slot[ "item" ] . as_object ( ) {
62- Some ( item) => item,
63- None => return Err ( Box :: new ( APIError :: BadFormat ) ) ,
64- } ;
65-
66- let price = item[ "price" ] . as_u64 ( ) . unwrap ( ) ;
67- let slot_number = slot[ "number" ] . as_u64 ( ) . unwrap ( ) ;
68- let name = item[ "name" ] . as_str ( ) . unwrap ( ) ;
69- print ! ( "{}. {} ({} Credits)" , slot_number, name, price) ;
70- if slot[ "empty" ] . as_bool ( ) . unwrap ( ) {
71- print ! ( " [EMPTY]" ) ;
84+ let drinks: Drinks = client. send ( request) ?. json ( ) ?;
85+ for machine in drinks. machines {
86+ term. fg ( term:: color:: CYAN ) . unwrap ( ) ;
87+ writeln ! ( term, "{}" , machine) . unwrap ( ) ;
88+ for slot in machine. slots {
89+ match slot. count {
90+ Some ( 0 ) => term. fg ( term:: color:: RED ) ,
91+ Some ( _) => term. reset ( ) ,
92+ None => {
93+ if slot. empty || !slot. active {
94+ term. fg ( term:: color:: RED )
95+ } else {
96+ term. reset ( )
97+ }
98+ }
7299 }
73- println ! ( "" ) ;
100+ . unwrap ( ) ;
101+ writeln ! ( term, "{}" , slot) . unwrap ( ) ;
74102 }
103+ println ! ( "" ) ;
104+ term. reset ( ) . unwrap ( ) ;
75105 }
106+ term. flush ( ) . unwrap ( ) ;
76107 return Ok ( ( ) ) ;
77108}
0 commit comments