55
66// spell-checker:ignore (path) eacces inacc rm-r4
77
8- use clap:: { Arg , ArgAction , Command , builder:: ValueParser , parser:: ValueSource } ;
8+ use clap:: builder:: { PossibleValue , ValueParser } ;
9+ use clap:: { Arg , ArgAction , Command , parser:: ValueSource } ;
910use std:: ffi:: { OsStr , OsString } ;
1011use std:: fs:: { self , Metadata } ;
1112use std:: io:: { IsTerminal , stdin} ;
@@ -19,6 +20,7 @@ use std::path::{Path, PathBuf};
1920use thiserror:: Error ;
2021use uucore:: display:: Quotable ;
2122use uucore:: error:: { FromIo , UError , UResult } ;
23+ use uucore:: parser:: shortcut_value_parser:: ShortcutValueParser ;
2224use uucore:: translate;
2325
2426use uucore:: { format_usage, os_str_as_bytes, prompt_yes, show_error} ;
@@ -27,8 +29,6 @@ use uucore::{format_usage, os_str_as_bytes, prompt_yes, show_error};
2729enum RmError {
2830 #[ error( "{}" , translate!( "rm-error-missing-operand" , "util_name" => uucore:: execution_phrase( ) ) ) ]
2931 MissingOperand ,
30- #[ error( "{}" , translate!( "rm-error-invalid-interactive-argument" , "arg" => _0. clone( ) ) ) ]
31- InvalidInteractiveArgument ( String ) ,
3232 #[ error( "{}" , translate!( "rm-error-cannot-remove-no-such-file" , "file" => _0. quote( ) ) ) ]
3333 CannotRemoveNoSuchFile ( String ) ,
3434 #[ error( "{}" , translate!( "rm-error-cannot-remove-permission-denied" , "file" => _0. quote( ) ) ) ]
@@ -59,6 +59,20 @@ pub enum InteractiveMode {
5959 PromptProtected ,
6060}
6161
62+ // We implement `From` instead of `TryFrom` because clap guarantees that we only receive valid values.
63+ //
64+ // The `PromptProtected` variant is not supposed to be created from a string.
65+ impl From < & str > for InteractiveMode {
66+ fn from ( s : & str ) -> Self {
67+ match s {
68+ "never" => Self :: Never ,
69+ "once" => Self :: Once ,
70+ "always" => Self :: Always ,
71+ _ => unreachable ! ( "should be prevented by clap" ) ,
72+ }
73+ }
74+ }
75+
6276/// Options for the `rm` command
6377///
6478/// All options are public so that the options can be programmatically
@@ -165,14 +179,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
165179 } else if matches. get_flag ( OPT_PROMPT_ONCE ) {
166180 InteractiveMode :: Once
167181 } else if matches. contains_id ( OPT_INTERACTIVE ) {
168- match matches. get_one :: < String > ( OPT_INTERACTIVE ) . unwrap ( ) . as_str ( ) {
169- "never" => InteractiveMode :: Never ,
170- "once" => InteractiveMode :: Once ,
171- "always" => InteractiveMode :: Always ,
172- val => {
173- return Err ( RmError :: InvalidInteractiveArgument ( val. to_string ( ) ) . into ( ) ) ;
174- }
175- }
182+ InteractiveMode :: from ( matches. get_one :: < String > ( OPT_INTERACTIVE ) . unwrap ( ) . as_str ( ) )
176183 } else {
177184 InteractiveMode :: PromptProtected
178185 }
@@ -249,6 +256,11 @@ pub fn uu_app() -> Command {
249256 . long ( OPT_INTERACTIVE )
250257 . help ( translate ! ( "rm-help-interactive" ) )
251258 . value_name ( "WHEN" )
259+ . value_parser ( ShortcutValueParser :: new ( [
260+ PossibleValue :: new ( "always" ) . alias ( "yes" ) ,
261+ PossibleValue :: new ( "once" ) ,
262+ PossibleValue :: new ( "never" ) . alias ( "no" ) . alias ( "none" ) ,
263+ ] ) )
252264 . num_args ( 0 ..=1 )
253265 . require_equals ( true )
254266 . default_missing_value ( "always" )
0 commit comments