forked from extern/nushell
base64 command more friendly (#5680)
* base64 command more friendly * using match instead of so much else if..
This commit is contained in:
parent
8259d463aa
commit
f5519e2a09
@ -8,7 +8,7 @@ use nu_protocol::{
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Base64Config {
|
pub struct Base64Config {
|
||||||
pub character_set: String,
|
pub character_set: Spanned<String>,
|
||||||
pub action_type: ActionType,
|
pub action_type: ActionType,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,8 +120,11 @@ fn operate(
|
|||||||
|
|
||||||
// Default the character set to standard if the argument is not specified.
|
// Default the character set to standard if the argument is not specified.
|
||||||
let character_set = match character_set {
|
let character_set = match character_set {
|
||||||
Some(inner_tag) => inner_tag.item,
|
Some(inner_tag) => inner_tag,
|
||||||
None => "standard".to_string(),
|
None => Spanned {
|
||||||
|
item: "standard".to_string(),
|
||||||
|
span: head, // actually this span is always useless, because default character_set is always valid.
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let encoding_config = Base64Config {
|
let encoding_config = Base64Config {
|
||||||
@ -166,35 +169,38 @@ fn action(
|
|||||||
base64_config: &Base64Config,
|
base64_config: &Base64Config,
|
||||||
command_span: &Span,
|
command_span: &Span,
|
||||||
) -> Result<Value, ShellError> {
|
) -> Result<Value, ShellError> {
|
||||||
match input {
|
let config_character_set = &base64_config.character_set;
|
||||||
Value::String { val, span } => {
|
let base64_config_enum: base64::Config = match config_character_set.item.as_str() {
|
||||||
let base64_config_enum: base64::Config = if &base64_config.character_set == "standard" {
|
"standard" => base64::STANDARD,
|
||||||
base64::STANDARD
|
"standard-no-padding" => base64::STANDARD_NO_PAD,
|
||||||
} else if &base64_config.character_set == "standard-no-padding" {
|
"url-safe" => base64::URL_SAFE,
|
||||||
base64::STANDARD_NO_PAD
|
"url-safe-no-padding" => base64::URL_SAFE_NO_PAD,
|
||||||
} else if &base64_config.character_set == "url-safe" {
|
"binhex" => base64::BINHEX,
|
||||||
base64::URL_SAFE
|
"bcrypt" => base64::BCRYPT,
|
||||||
} else if &base64_config.character_set == "url-safe-no-padding" {
|
"crypt" => base64::CRYPT,
|
||||||
base64::URL_SAFE_NO_PAD
|
not_valid => return Err(ShellError::GenericError(
|
||||||
} else if &base64_config.character_set == "binhex" {
|
|
||||||
base64::BINHEX
|
|
||||||
} else if &base64_config.character_set == "bcrypt" {
|
|
||||||
base64::BCRYPT
|
|
||||||
} else if &base64_config.character_set == "crypt" {
|
|
||||||
base64::CRYPT
|
|
||||||
} else {
|
|
||||||
return Err(ShellError::GenericError(
|
|
||||||
"value is not an accepted character set".to_string(),
|
"value is not an accepted character set".to_string(),
|
||||||
format!(
|
format!(
|
||||||
"{} is not a valid character-set.\nPlease use `help hash base64` to see a list of valid character sets.",
|
"{} is not a valid character-set.\nPlease use `help hash base64` to see a list of valid character sets.",
|
||||||
&base64_config.character_set
|
not_valid
|
||||||
),
|
),
|
||||||
Some(*span),
|
Some(config_character_set.span),
|
||||||
None,
|
None,
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
));
|
))
|
||||||
};
|
};
|
||||||
|
match input {
|
||||||
|
Value::Binary { val, .. } => match base64_config.action_type {
|
||||||
|
ActionType::Encode => Ok(Value::string(
|
||||||
|
encode_config(&val, base64_config_enum),
|
||||||
|
*command_span,
|
||||||
|
)),
|
||||||
|
ActionType::Decode => Err(ShellError::UnsupportedInput(
|
||||||
|
"Binary data can only support encoding".to_string(),
|
||||||
|
*command_span,
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
Value::String { val, .. } => {
|
||||||
match base64_config.action_type {
|
match base64_config.action_type {
|
||||||
ActionType::Encode => Ok(Value::string(
|
ActionType::Encode => Ok(Value::string(
|
||||||
encode_config(&val, base64_config_enum),
|
encode_config(&val, base64_config_enum),
|
||||||
@ -202,6 +208,9 @@ fn action(
|
|||||||
)),
|
)),
|
||||||
|
|
||||||
ActionType::Decode => {
|
ActionType::Decode => {
|
||||||
|
// for decode, input val may contains invalid new line character, which is ok to omitted them by default.
|
||||||
|
let val = val.clone();
|
||||||
|
let val = val.replace("\r\n", "").replace('\n', "");
|
||||||
let decode_result = decode_config(&val, base64_config_enum);
|
let decode_result = decode_config(&val, base64_config_enum);
|
||||||
|
|
||||||
match decode_result {
|
match decode_result {
|
||||||
@ -213,7 +222,7 @@ fn action(
|
|||||||
"value could not be base64 decoded".to_string(),
|
"value could not be base64 decoded".to_string(),
|
||||||
format!(
|
format!(
|
||||||
"invalid base64 input for character set {}",
|
"invalid base64 input for character set {}",
|
||||||
&base64_config.character_set
|
&config_character_set.item
|
||||||
),
|
),
|
||||||
Some(*command_span),
|
Some(*command_span),
|
||||||
None,
|
None,
|
||||||
@ -233,7 +242,7 @@ fn action(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{action, ActionType, Base64, Base64Config};
|
use super::{action, ActionType, Base64, Base64Config};
|
||||||
use nu_protocol::{Span, Value};
|
use nu_protocol::{Span, Spanned, Value};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_examples() {
|
fn test_examples() {
|
||||||
@ -249,7 +258,10 @@ mod tests {
|
|||||||
let actual = action(
|
let actual = action(
|
||||||
&word,
|
&word,
|
||||||
&Base64Config {
|
&Base64Config {
|
||||||
character_set: "standard".to_string(),
|
character_set: Spanned {
|
||||||
|
item: "standard".to_string(),
|
||||||
|
span: Span::test_data(),
|
||||||
|
},
|
||||||
action_type: ActionType::Encode,
|
action_type: ActionType::Encode,
|
||||||
},
|
},
|
||||||
&Span::test_data(),
|
&Span::test_data(),
|
||||||
@ -266,7 +278,10 @@ mod tests {
|
|||||||
let actual = action(
|
let actual = action(
|
||||||
&word,
|
&word,
|
||||||
&Base64Config {
|
&Base64Config {
|
||||||
character_set: "standard-no-padding".to_string(),
|
character_set: Spanned {
|
||||||
|
item: "standard-no-padding".to_string(),
|
||||||
|
span: Span::test_data(),
|
||||||
|
},
|
||||||
action_type: ActionType::Encode,
|
action_type: ActionType::Encode,
|
||||||
},
|
},
|
||||||
&Span::test_data(),
|
&Span::test_data(),
|
||||||
@ -283,7 +298,10 @@ mod tests {
|
|||||||
let actual = action(
|
let actual = action(
|
||||||
&word,
|
&word,
|
||||||
&Base64Config {
|
&Base64Config {
|
||||||
character_set: "url-safe".to_string(),
|
character_set: Spanned {
|
||||||
|
item: "url-safe".to_string(),
|
||||||
|
span: Span::test_data(),
|
||||||
|
},
|
||||||
action_type: ActionType::Encode,
|
action_type: ActionType::Encode,
|
||||||
},
|
},
|
||||||
&Span::test_data(),
|
&Span::test_data(),
|
||||||
@ -300,7 +318,10 @@ mod tests {
|
|||||||
let actual = action(
|
let actual = action(
|
||||||
&word,
|
&word,
|
||||||
&Base64Config {
|
&Base64Config {
|
||||||
character_set: "binhex".to_string(),
|
character_set: Spanned {
|
||||||
|
item: "binhex".to_string(),
|
||||||
|
span: Span::test_data(),
|
||||||
|
},
|
||||||
action_type: ActionType::Decode,
|
action_type: ActionType::Decode,
|
||||||
},
|
},
|
||||||
&Span::test_data(),
|
&Span::test_data(),
|
||||||
@ -308,4 +329,68 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn base64_decode_binhex_with_new_line_input() {
|
||||||
|
let word = Value::string("A5\"KC9jRB\n@IIF'8bF!", Span::test_data());
|
||||||
|
let expected = Value::string("a binhex test", Span::test_data());
|
||||||
|
|
||||||
|
let actual = action(
|
||||||
|
&word,
|
||||||
|
&Base64Config {
|
||||||
|
character_set: Spanned {
|
||||||
|
item: "binhex".to_string(),
|
||||||
|
span: Span::test_data(),
|
||||||
|
},
|
||||||
|
action_type: ActionType::Decode,
|
||||||
|
},
|
||||||
|
&Span::test_data(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn base64_encode_binary() {
|
||||||
|
let word = Value::Binary {
|
||||||
|
val: vec![77, 97, 110],
|
||||||
|
span: Span::test_data(),
|
||||||
|
};
|
||||||
|
let expected = Value::string("TWFu", Span::test_data());
|
||||||
|
|
||||||
|
let actual = action(
|
||||||
|
&word,
|
||||||
|
&Base64Config {
|
||||||
|
character_set: Spanned {
|
||||||
|
item: "standard".to_string(),
|
||||||
|
span: Span::test_data(),
|
||||||
|
},
|
||||||
|
action_type: ActionType::Encode,
|
||||||
|
},
|
||||||
|
&Span::test_data(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn base64_decode_binary_expect_error() {
|
||||||
|
let word = Value::Binary {
|
||||||
|
val: vec![77, 97, 110],
|
||||||
|
span: Span::test_data(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let actual = action(
|
||||||
|
&word,
|
||||||
|
&Base64Config {
|
||||||
|
character_set: Spanned {
|
||||||
|
item: "standard".to_string(),
|
||||||
|
span: Span::test_data(),
|
||||||
|
},
|
||||||
|
action_type: ActionType::Decode,
|
||||||
|
},
|
||||||
|
&Span::test_data(),
|
||||||
|
);
|
||||||
|
assert!(actual.is_err())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user