1- use std:: io:: { self , Write } ;
1+ use std:: io:: { self , BufRead , Write } ;
2+
3+ #[ cfg( unix) ]
4+ use std:: fs:: File ;
5+ #[ cfg( windows) ]
6+ use std:: fs:: OpenOptions ;
27
38use clap:: Args ;
49use color_eyre:: eyre:: eyre;
@@ -30,8 +35,6 @@ impl SubcommandExecutor for DeleteArgs {
3035 . or_else ( || get_first_matching_element ( & otp_database, & self ) )
3136 . ok_or ( eyre ! ( "No code has been found using the given arguments" ) ) ?;
3237
33- let mut output = String :: with_capacity ( 1 ) ;
34-
3538 let element = otp_database. elements_ref ( ) . get ( index_to_delete) . unwrap ( ) ;
3639 print ! (
3740 "Are you sure you want to delete the {}th code ({}, {}) [Y,N]: " ,
@@ -41,7 +44,7 @@ impl SubcommandExecutor for DeleteArgs {
4144 ) ;
4245 io:: stdout ( ) . flush ( ) ?;
4346
44- io :: stdin ( ) . read_line ( & mut output) ?;
47+ let output = read_confirmation_line ( ) ?;
4548
4649 if output. trim ( ) . eq_ignore_ascii_case ( "y" ) {
4750 otp_database. delete_element ( index_to_delete) ;
@@ -52,6 +55,35 @@ impl SubcommandExecutor for DeleteArgs {
5255 }
5356}
5457
58+ fn read_confirmation_line ( ) -> color_eyre:: Result < String > {
59+ let mut output = String :: with_capacity ( 1 ) ;
60+
61+ if io:: stdin ( ) . read_line ( & mut output) ? > 0 {
62+ return Ok ( output) ;
63+ }
64+
65+ #[ cfg( unix) ]
66+ {
67+ output. clear ( ) ;
68+ let mut tty = io:: BufReader :: new ( File :: open ( "/dev/tty" ) ?) ;
69+ tty. read_line ( & mut output) ?;
70+ return Ok ( output) ;
71+ }
72+
73+ #[ cfg( windows) ]
74+ {
75+ output. clear ( ) ;
76+ let mut tty = io:: BufReader :: new ( OpenOptions :: new ( ) . read ( true ) . open ( "CONIN$" ) ?) ;
77+ tty. read_line ( & mut output) ?;
78+ return Ok ( output) ;
79+ }
80+
81+ #[ allow( unreachable_code) ]
82+ Err ( eyre ! (
83+ "Unable to read confirmation answer from standard input or terminal"
84+ ) )
85+ }
86+
5587fn get_first_matching_element (
5688 otp_database : & OTPDatabase ,
5789 delete_args : & DeleteArgs ,
0 commit comments