Mid-refactor
This commit is contained in:
parent
ec9089ebc5
commit
51b0f97fda
|
@ -179,8 +179,6 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState {
|
|||
Char,
|
||||
Decode,
|
||||
Encode,
|
||||
EncodeBase,
|
||||
DecodeBase,
|
||||
DecodeBase64,
|
||||
EncodeBase64,
|
||||
DetectColumns,
|
||||
|
|
62
crates/nu-command/src/strings/base/base32.rs
Normal file
62
crates/nu-command/src/strings/base/base32.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
use data_encoding::Encoding;
|
||||
|
||||
use nu_engine::command_prelude::*;
|
||||
|
||||
pub struct Base32Config {
|
||||
lower: bool,
|
||||
lower_span: Option<Span>,
|
||||
nopad: bool,
|
||||
nopad_span: Option<Span>,
|
||||
dnscurve: bool,
|
||||
dnscurve_span: Option<Span>,
|
||||
dnssec: bool,
|
||||
dnssec_span: Option<Span>,
|
||||
}
|
||||
|
||||
impl Base32Config {
|
||||
pub fn new(engine_state: &EngineState, stack: &mut Stack, call: &Call) -> Self {
|
||||
Base32Config {
|
||||
lower: call.get_flag(engine_state, stack, "lower"),
|
||||
lower_span: call.get_flag_span(stack, "lower"),
|
||||
nopad: call.get_flag(engine_state, stack, "nopad"),
|
||||
nopad_span: call.get_flag_span(stack, "nopad"),
|
||||
dnscurve: call.get_flag(engine_state, stack, "dnscurve"),
|
||||
dnscurve_span: call.get_flag_span(stack, "dnscurve"),
|
||||
dnssec: call.get_flag(engine_state, stack, "dnssec"),
|
||||
dnssec_span: call.get_flag_span(stack, "dnssec"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn base32_encoding(config: Base32Config) -> Result<Encoding, ShellError> {
|
||||
if let Some(dnscurve_span) = config.dnscurve_span {
|
||||
if let Some(lower_span) = config.lower_span {
|
||||
return Err(ShellError::IncompatibleParameters {
|
||||
left_message: "Inapplicable to DNSCURVE".to_string(),
|
||||
left_span: lower_span,
|
||||
right_message: "DNSCURVE must be used standalone".to_string(),
|
||||
right_span: dnscurve_span,
|
||||
});
|
||||
}
|
||||
if let Some(nopad_span) = config.nopad_span {
|
||||
return Err(ShellError::IncompatibleParameters {
|
||||
left_message: "Inapplicable to DNSCURVE".to_string(),
|
||||
left_span: nopad_span,
|
||||
right_message: "DNSCURVE must be used standalone".to_string(),
|
||||
right_span: dnscurve_span,
|
||||
});
|
||||
}
|
||||
if let Some(dnssec) = config.dnssec_span {
|
||||
return Err(ShellError::IncompatibleParameters {
|
||||
left_message: "Inapplicable to DNSCURVE".to_string(),
|
||||
left_span: nopad_span,
|
||||
right_message: "DNSCURVE must be used standalone".to_string(),
|
||||
right_span: dnscurve_span,
|
||||
});
|
||||
}
|
||||
|
||||
return Ok(data_encoding::BASE32_DNSCURVE);
|
||||
}
|
||||
|
||||
todo!()
|
||||
}
|
66
crates/nu-command/src/strings/base/decode_base32.rs
Normal file
66
crates/nu-command/src/strings/base/decode_base32.rs
Normal file
|
@ -0,0 +1,66 @@
|
|||
use nu_engine::command_prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DecodeBase32;
|
||||
|
||||
impl Command for DecodeBase32 {
|
||||
fn name(&self) -> &str {
|
||||
"decode base32"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("decode base32")
|
||||
.input_output_types(vec![(Type::String, Type::Binary)])
|
||||
.allow_variants_without_examples(true)
|
||||
.switch("lower", "Use a lowercase version of Base32.", None)
|
||||
.switch("nopad", "Do not pad the output.", None)
|
||||
.switch("dnscurve", "Use DNSCURVE Base32 variant.", None)
|
||||
.switch("dnssec", "Use DNSSEC Base32 variant.", None)
|
||||
.category(Category::Formats)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Decode a value."
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"TODO"
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn is_const(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn run_const(
|
||||
&self,
|
||||
working_set: &StateWorkingSet,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
crate::test_examples(DecodeBase32)
|
||||
}
|
||||
}
|
67
crates/nu-command/src/strings/base/decode_base32hex.rs
Normal file
67
crates/nu-command/src/strings/base/decode_base32hex.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
use nu_engine::command_prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DecodeBase;
|
||||
|
||||
impl Command for DecodeBase {
|
||||
fn name(&self) -> &str {
|
||||
"decode base"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("decode base")
|
||||
.input_output_types(vec![(Type::String, Type::Binary)])
|
||||
.allow_variants_without_examples(true)
|
||||
.required("encoding", SyntaxShape::String, "encoding to use")
|
||||
.category(Category::Formats)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Decode a value."
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"TODO"
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn is_const(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name: String = call.req(engine_state, stack, 0)?;
|
||||
|
||||
decode(&name, call.span(), input)
|
||||
}
|
||||
|
||||
fn run_const(
|
||||
&self,
|
||||
working_set: &StateWorkingSet,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name: String = call.req_const(working_set, 0)?;
|
||||
|
||||
decode(&name, call.span(), input)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
crate::test_examples(DecodeBase)
|
||||
}
|
||||
}
|
76
crates/nu-command/src/strings/base/decode_hex.rs
Normal file
76
crates/nu-command/src/strings/base/decode_hex.rs
Normal file
|
@ -0,0 +1,76 @@
|
|||
use nu_engine::command_prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DecodeBase;
|
||||
|
||||
impl Command for DecodeBase {
|
||||
fn name(&self) -> &str {
|
||||
"decode base"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("decode base")
|
||||
.input_output_types(vec![(Type::String, Type::Binary)])
|
||||
.allow_variants_without_examples(true)
|
||||
.required("encoding", SyntaxShape::String, "encoding to use")
|
||||
.category(Category::Formats)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Decode a value."
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"TODO"
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn is_const(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name: String = call.req(engine_state, stack, 0)?;
|
||||
|
||||
decode(&name, call.span(), input)
|
||||
}
|
||||
|
||||
fn run_const(
|
||||
&self,
|
||||
working_set: &StateWorkingSet,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name: String = call.req_const(working_set, 0)?;
|
||||
|
||||
decode(&name, call.span(), input)
|
||||
}
|
||||
}
|
||||
|
||||
fn decode(name: &str, call_span: Span, input: PipelineData) -> Result<PipelineData, ShellError> {
|
||||
let encoding = super::encoding(&name, call_span, call_span)?;
|
||||
let metadata = input.metadata();
|
||||
let (input_str, input_span) = super::get_string(input, call_span)?;
|
||||
let output = encoding.decode(input_str.as_bytes()).unwrap();
|
||||
|
||||
Ok(Value::binary(output, call_span).into_pipeline_data_with_metadata(metadata))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
crate::test_examples(DecodeBase)
|
||||
}
|
||||
}
|
70
crates/nu-command/src/strings/base/encode_base32.rs
Normal file
70
crates/nu-command/src/strings/base/encode_base32.rs
Normal file
|
@ -0,0 +1,70 @@
|
|||
use nu_engine::command_prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct EncodeBase;
|
||||
|
||||
impl Command for EncodeBase {
|
||||
fn name(&self) -> &str {
|
||||
"encode base"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("encode base")
|
||||
.input_output_types(vec![
|
||||
(Type::String, Type::String),
|
||||
(Type::Binary, Type::String),
|
||||
])
|
||||
.allow_variants_without_examples(true)
|
||||
.required("encoding", SyntaxShape::String, "encoding to use")
|
||||
.category(Category::Formats)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Encode a value."
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"TODO"
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn is_const(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name: String = call.req(engine_state, stack, 0)?;
|
||||
|
||||
encode(&name, call.span(), input)
|
||||
}
|
||||
|
||||
fn run_const(
|
||||
&self,
|
||||
working_set: &StateWorkingSet,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name: String = call.req_const(working_set, 0)?;
|
||||
|
||||
encode(&name, call.span(), input)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
crate::test_examples(EncodeBase)
|
||||
}
|
||||
}
|
79
crates/nu-command/src/strings/base/encode_base64.rs
Normal file
79
crates/nu-command/src/strings/base/encode_base64.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
use nu_engine::command_prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct EncodeBase;
|
||||
|
||||
impl Command for EncodeBase {
|
||||
fn name(&self) -> &str {
|
||||
"encode base"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("encode base")
|
||||
.input_output_types(vec![
|
||||
(Type::String, Type::String),
|
||||
(Type::Binary, Type::String),
|
||||
])
|
||||
.allow_variants_without_examples(true)
|
||||
.required("encoding", SyntaxShape::String, "encoding to use")
|
||||
.category(Category::Formats)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Encode a value."
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"TODO"
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn is_const(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name: String = call.req(engine_state, stack, 0)?;
|
||||
|
||||
encode(&name, call.span(), input)
|
||||
}
|
||||
|
||||
fn run_const(
|
||||
&self,
|
||||
working_set: &StateWorkingSet,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name: String = call.req_const(working_set, 0)?;
|
||||
|
||||
encode(&name, call.span(), input)
|
||||
}
|
||||
}
|
||||
|
||||
fn encode(name: &str, call_span: Span, input: PipelineData) -> Result<PipelineData, ShellError> {
|
||||
let encoding = super::encoding(name, call_span, call_span)?;
|
||||
let metadata = input.metadata();
|
||||
let (input_bytes, input_span) = super::get_binary(input, call_span)?;
|
||||
let output = encoding.encode(&input_bytes);
|
||||
|
||||
Ok(Value::string(output, call_span).into_pipeline_data_with_metadata(metadata))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
crate::test_examples(EncodeBase)
|
||||
}
|
||||
}
|
79
crates/nu-command/src/strings/base/encode_hex.rs
Normal file
79
crates/nu-command/src/strings/base/encode_hex.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
use nu_engine::command_prelude::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct EncodeBase;
|
||||
|
||||
impl Command for EncodeBase {
|
||||
fn name(&self) -> &str {
|
||||
"encode base"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("encode base")
|
||||
.input_output_types(vec![
|
||||
(Type::String, Type::String),
|
||||
(Type::Binary, Type::String),
|
||||
])
|
||||
.allow_variants_without_examples(true)
|
||||
.required("encoding", SyntaxShape::String, "encoding to use")
|
||||
.category(Category::Formats)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Encode a value."
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
"TODO"
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn is_const(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name: String = call.req(engine_state, stack, 0)?;
|
||||
|
||||
encode(&name, call.span(), input)
|
||||
}
|
||||
|
||||
fn run_const(
|
||||
&self,
|
||||
working_set: &StateWorkingSet,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name: String = call.req_const(working_set, 0)?;
|
||||
|
||||
encode(&name, call.span(), input)
|
||||
}
|
||||
}
|
||||
|
||||
fn encode(name: &str, call_span: Span, input: PipelineData) -> Result<PipelineData, ShellError> {
|
||||
let encoding = super::encoding(name, call_span, call_span)?;
|
||||
let metadata = input.metadata();
|
||||
let (input_bytes, input_span) = super::get_binary(input, call_span)?;
|
||||
let output = encoding.encode(&input_bytes);
|
||||
|
||||
Ok(Value::string(output, call_span).into_pipeline_data_with_metadata(metadata))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
crate::test_examples(EncodeBase)
|
||||
}
|
||||
}
|
|
@ -1,42 +1,52 @@
|
|||
use nu_protocol::{PipelineData, ShellError, Span, Value};
|
||||
use data_encoding::Encoding;
|
||||
|
||||
mod decode;
|
||||
mod encode;
|
||||
use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Span, Value};
|
||||
|
||||
pub use decode::DecodeBase;
|
||||
pub use encode::EncodeBase;
|
||||
mod decode_base32;
|
||||
mod decode_base32hex;
|
||||
mod decode_base64;
|
||||
mod decode_hex;
|
||||
mod encode_base32;
|
||||
mod encode_base32hex;
|
||||
mod encode_base64;
|
||||
mod encode_hex;
|
||||
|
||||
pub fn encoding(
|
||||
name: &str,
|
||||
val_span: Span,
|
||||
mod base32;
|
||||
|
||||
fn decode(
|
||||
encoding: Encoding,
|
||||
call_span: Span,
|
||||
) -> Result<data_encoding::Encoding, ShellError> {
|
||||
match name {
|
||||
"base32" => Ok(data_encoding::BASE32),
|
||||
"base32hex" => Ok(data_encoding::BASE32HEX),
|
||||
"base32hex_nopad" => Ok(data_encoding::BASE32HEX_NOPAD),
|
||||
"base32_dnscurve" => Ok(data_encoding::BASE32_DNSCURVE),
|
||||
"base32_dnssec" => Ok(data_encoding::BASE32_DNSSEC),
|
||||
"base32_nopad" => Ok(data_encoding::BASE32_NOPAD),
|
||||
"base64" => Ok(data_encoding::BASE64),
|
||||
"base64url" => Ok(data_encoding::BASE64URL),
|
||||
"base64url_nopad" => Ok(data_encoding::BASE64URL_NOPAD),
|
||||
"base64_mime" => Ok(data_encoding::BASE64_MIME),
|
||||
"base64_mime_permissive" => Ok(data_encoding::BASE64_MIME_PERMISSIVE),
|
||||
"base64_nopad" => Ok(data_encoding::BASE64_NOPAD),
|
||||
"hexlower" => Ok(data_encoding::HEXLOWER),
|
||||
"hexlower_permissive" => Ok(data_encoding::HEXLOWER_PERMISSIVE),
|
||||
"hexupper" => Ok(data_encoding::HEXUPPER),
|
||||
"hexupper_permissive" => Ok(data_encoding::HEXUPPER_PERMISSIVE),
|
||||
_ => Err(ShellError::IncorrectValue {
|
||||
msg: format!("Encoding '{name}' not found"),
|
||||
val_span,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let metadata = input.metadata();
|
||||
let (input_str, input_span) = get_string(input, call_span)?;
|
||||
let output = match encoding.decode(input_str.as_bytes()) {
|
||||
Ok(output) => output,
|
||||
Err(err) => {
|
||||
return Err(ShellError::IncorrectValue {
|
||||
msg: err.to_string(),
|
||||
val_span: input_span,
|
||||
call_span,
|
||||
}),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Value::binary(output, call_span).into_pipeline_data_with_metadata(metadata))
|
||||
}
|
||||
|
||||
pub fn get_string(input: PipelineData, call_span: Span) -> Result<(String, Span), ShellError> {
|
||||
fn encode(
|
||||
encoding: Encoding,
|
||||
call_span: Span,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let metadata = input.metadata();
|
||||
let (input_bytes, _) = get_binary(input, call_span)?;
|
||||
let output = encoding.encode(&input_bytes);
|
||||
|
||||
Ok(Value::string(output, call_span).into_pipeline_data_with_metadata(metadata))
|
||||
}
|
||||
|
||||
fn get_string(input: PipelineData, call_span: Span) -> Result<(String, Span), ShellError> {
|
||||
match input {
|
||||
PipelineData::Value(val, ..) => {
|
||||
let span = val.span();
|
||||
|
@ -55,13 +65,13 @@ pub fn get_string(input: PipelineData, call_span: Span) -> Result<(String, Span)
|
|||
let span = stream.span();
|
||||
Ok((stream.into_string()?, span))
|
||||
}
|
||||
PipelineData::Empty => {
|
||||
todo!("Can't have empty data");
|
||||
}
|
||||
PipelineData::Empty => Err(ShellError::PipelineEmpty {
|
||||
dst_span: call_span,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_binary(input: PipelineData, call_span: Span) -> Result<(Vec<u8>, Span), ShellError> {
|
||||
fn get_binary(input: PipelineData, call_span: Span) -> Result<(Vec<u8>, Span), ShellError> {
|
||||
match input {
|
||||
PipelineData::Value(val, ..) => {
|
||||
let span = val.span();
|
||||
|
|
Loading…
Reference in New Issue
Block a user