@@ -31,6 +31,32 @@ const PROMPT_MAIN: &str = " >> ";
31
31
/// red ` >` with [`ShellHelper`]
32
32
const PROMPT_SECONDARY : & str = " > " ;
33
33
34
+ /// Errors raised by [`match_plot_album_relative()`] and
35
+ /// [`match_plot_song_relative`]
36
+ ///
37
+ /// when user argument for relative to what is invalid
38
+ #[ derive( Debug ) ]
39
+ enum InvalidArgumentError {
40
+ /// Error message: Invalid argument! Try using 'all' or 'artist' next time
41
+ Artist ,
42
+ /// Error message: Invalid argument! Try using 'all', 'artist' or 'album' next time
43
+ Album ,
44
+ }
45
+ impl std:: fmt:: Display for InvalidArgumentError {
46
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
47
+ match self {
48
+ InvalidArgumentError :: Artist => {
49
+ write ! ( f, "Invalid argument! Try using 'all' or 'artist' next time" )
50
+ }
51
+ InvalidArgumentError :: Album => write ! (
52
+ f,
53
+ "Invalid argument! Try using 'all', 'artist' or 'album' next time"
54
+ ) ,
55
+ }
56
+ }
57
+ }
58
+ impl Error for InvalidArgumentError { }
59
+
34
60
/// Helper for [`Editor`]
35
61
#[ derive( Completer , Helper , Hinter , Validator ) ]
36
62
struct ShellHelper ;
@@ -133,7 +159,8 @@ pub fn start(entries: &SongEntries) {
133
159
134
160
/// Handles errors thrown by [`match_input()`] in [`start()`]
135
161
///
136
- /// Prints error messages for [`NotFoundError`],
162
+ /// Prints error messages for
163
+ /// [`NotFoundError`], [`InvalidArgumentError`]
137
164
/// [`ParseError`][`chrono::format::ParseError`],
138
165
/// and [`ParseIntError`][`std::num::ParseIntError`]
139
166
#[ allow( clippy:: borrowed_box) ]
@@ -142,6 +169,7 @@ fn handle_error(err: &Box<dyn Error>) {
142
169
// also thx ChatGPT
143
170
match err. as_ref ( ) {
144
171
not_found if not_found. is :: < NotFoundError > ( ) => eprintln ! ( "{not_found}" ) ,
172
+ invalid_arg if invalid_arg. is :: < InvalidArgumentError > ( ) => eprintln ! ( "{invalid_arg}" ) ,
145
173
date if date. is :: < chrono:: format:: ParseError > ( ) => {
146
174
eprintln ! ( "Invalid date! Make sure you input the date in YYYY-MM-DD format." ) ;
147
175
}
@@ -175,6 +203,8 @@ fn match_input(
175
203
"print top songs" | "ptsons" => match_print_top ( entries, rl, & Aspect :: Songs ) ?,
176
204
"plot artist" | "gart" => match_plot_artist ( entries, rl) ?,
177
205
"plot artist relative" | "gartr" => match_plot_artist_relative ( entries, rl) ?,
206
+ "plot album relative" | "galbr" => match_plot_album_relative ( entries, rl) ?,
207
+ "plot song relative" | "gsonr" => match_plot_song_relative ( entries, rl) ?,
178
208
// when you press ENTER -> nothing happens, new prompt
179
209
"" => ( ) ,
180
210
_ => {
@@ -451,7 +481,71 @@ fn match_plot_artist_relative(
451
481
let usr_input_art = rl. readline ( PROMPT_MAIN ) ?;
452
482
let art = entries. find ( ) . artist ( & usr_input_art) ?;
453
483
454
- entries. plot_artist_relative ( & art) ;
484
+ entries. plot_relative ( & art) ;
485
+ Ok ( ( ) )
486
+ }
487
+
488
+ /// Used by [`match_input()`] for `plot album relative` command
489
+ fn match_plot_album_relative (
490
+ entries : & SongEntries ,
491
+ rl : & mut Editor < ShellHelper , FileHistory > ,
492
+ ) -> Result < ( ) , Box < dyn Error > > {
493
+ // 1st prompt: artist name
494
+ println ! ( "Artist name?" ) ;
495
+ let usr_input_art = rl. readline ( PROMPT_MAIN ) ?;
496
+ let art = entries. find ( ) . artist ( & usr_input_art) ?;
497
+
498
+ // 2nd prompt: album name
499
+ println ! ( "Album name?" ) ;
500
+ let usr_input_alb = rl. readline ( PROMPT_MAIN ) ?;
501
+ let alb = entries. find ( ) . album ( & usr_input_alb, & art. name ) ?;
502
+
503
+ // 3rd prompt: relative to what
504
+ println ! ( "Relative to all or artist?" ) ;
505
+ let usr_input_rel = rl. readline ( PROMPT_SECONDARY ) ?;
506
+
507
+ match usr_input_rel. as_str ( ) {
508
+ "all" => entries. plot_relative ( & alb) ,
509
+ "artist" => entries. plot_relative_to_artist ( & alb) ,
510
+ _ => return Err ( Box :: new ( InvalidArgumentError :: Artist ) ) ,
511
+ }
512
+
513
+ Ok ( ( ) )
514
+ }
515
+
516
+ /// Used by [`match_input()`] for `plot song relative` command
517
+ fn match_plot_song_relative (
518
+ entries : & SongEntries ,
519
+ rl : & mut Editor < ShellHelper , FileHistory > ,
520
+ ) -> Result < ( ) , Box < dyn Error > > {
521
+ // 1st prompt: artist name
522
+ println ! ( "Artist name?" ) ;
523
+ let usr_input_art = rl. readline ( PROMPT_MAIN ) ?;
524
+ let art = entries. find ( ) . artist ( & usr_input_art) ?;
525
+
526
+ // 2nd prompt: album name
527
+ println ! ( "Album name?" ) ;
528
+ let usr_input_alb = rl. readline ( PROMPT_MAIN ) ?;
529
+ let alb = entries. find ( ) . album ( & usr_input_alb, & art. name ) ?;
530
+
531
+ // 3rd prompt: song name
532
+ println ! ( "Song name?" ) ;
533
+ let usr_input_son = rl. readline ( PROMPT_MAIN ) ?;
534
+ let son = entries
535
+ . find ( )
536
+ . song_from_album ( & usr_input_son, & alb. name , & alb. artist . name ) ?;
537
+
538
+ // 4th prompt: relative to what
539
+ println ! ( "Relative to all, artist or album?" ) ;
540
+ let usr_input_rel = rl. readline ( PROMPT_SECONDARY ) ?;
541
+
542
+ match usr_input_rel. as_str ( ) {
543
+ "all" => entries. plot_relative ( & son) ,
544
+ "artist" => entries. plot_relative_to_artist ( & son) ,
545
+ "album" => entries. plot_relative_to_album ( & son) ,
546
+ _ => return Err ( Box :: new ( InvalidArgumentError :: Album ) ) ,
547
+ }
548
+
455
549
Ok ( ( ) )
456
550
}
457
551
0 commit comments