mirror of
https://github.com/nushell/nushell.git
synced 2025-06-30 14:40:06 +02:00
add nu-pretty-hex, add into binary, update binaryview (#3370)
* add nu-pretty-hex, add into binary, update binaryview * updated parameter name, updated examples * fixed nu-pretty-hex test * fixed tests again! and added a no color option to pretty-hex
This commit is contained in:
@ -172,6 +172,7 @@ pub(crate) use echo::Echo;
|
||||
pub(crate) use empty::Command as Empty;
|
||||
pub(crate) use if_::If;
|
||||
pub(crate) use into::Into;
|
||||
pub(crate) use into::IntoBinary;
|
||||
pub(crate) use into::IntoInt;
|
||||
pub(crate) use nu::NuPlugin;
|
||||
pub(crate) use update::Command as Update;
|
||||
|
@ -165,7 +165,7 @@ pub fn autoview(context: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let result = binary.run_with_actions(command_args)?;
|
||||
let _ = result.collect::<Vec<_>>();
|
||||
} else {
|
||||
use pretty_hex::*;
|
||||
use nu_pretty_hex::*;
|
||||
out!("{:?}", b.hex_dump());
|
||||
}
|
||||
}
|
||||
|
@ -122,6 +122,7 @@ pub fn create_default_context(interactive: bool) -> Result<EvaluationContext, Bo
|
||||
whole_stream_command(Update),
|
||||
whole_stream_command(Insert),
|
||||
whole_stream_command(Into),
|
||||
whole_stream_command(IntoBinary),
|
||||
whole_stream_command(IntoInt),
|
||||
whole_stream_command(SplitBy),
|
||||
// Row manipulation
|
||||
|
170
crates/nu-command/src/commands/into/binary.rs
Normal file
170
crates/nu-command/src/commands/into/binary.rs
Normal file
@ -0,0 +1,170 @@
|
||||
use crate::prelude::*;
|
||||
use nu_engine::WholeStreamCommand;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use num_bigint::{BigInt, ToBigInt};
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Arguments {
|
||||
pub rest: Vec<ColumnPath>,
|
||||
}
|
||||
|
||||
impl WholeStreamCommand for SubCommand {
|
||||
fn name(&self) -> &str {
|
||||
"into binary"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("into binary").rest(
|
||||
SyntaxShape::ColumnPath,
|
||||
"column paths to convert to binary (for table input)",
|
||||
)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Convert value to a binary primitive"
|
||||
}
|
||||
|
||||
fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
into_binary(args)
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "convert string to a nushell binary primitive",
|
||||
example:
|
||||
"echo 'This is a string that is exactly 52 characters long.' | into binary",
|
||||
result: Some(vec![UntaggedValue::binary(
|
||||
"This is a string that is exactly 52 characters long."
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
)
|
||||
.into()]),
|
||||
},
|
||||
Example {
|
||||
description: "convert a number to a nushell binary primitive",
|
||||
example: "echo 1 | into binary",
|
||||
result: Some(vec![
|
||||
UntaggedValue::binary(BigInt::from(1).to_bytes_le().1).into()
|
||||
]),
|
||||
},
|
||||
Example {
|
||||
description: "convert a boolean to a nushell binary primitive",
|
||||
example: "echo $true | into binary",
|
||||
result: Some(vec![
|
||||
UntaggedValue::binary(BigInt::from(1).to_bytes_le().1).into()
|
||||
]),
|
||||
},
|
||||
Example {
|
||||
description: "convert a filesize to a nushell binary primitive",
|
||||
example: "ls | where name == LICENSE | get size | into binary",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "convert a filepath to a nushell binary primitive",
|
||||
example: "ls | where name == LICENSE | get name | path expand | into binary",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "convert a decimal to a nushell binary primitive",
|
||||
example: "echo 1.234 | into binary",
|
||||
result: Some(vec![
|
||||
UntaggedValue::binary(BigInt::from(1).to_bytes_le().1).into()
|
||||
]),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn into_binary(args: CommandArgs) -> Result<ActionStream, ShellError> {
|
||||
let (Arguments { rest: column_paths }, input) = args.process()?;
|
||||
|
||||
Ok(input
|
||||
.map(move |v| {
|
||||
if column_paths.is_empty() {
|
||||
ReturnSuccess::value(action(&v, v.tag())?)
|
||||
} else {
|
||||
let mut ret = v;
|
||||
for path in &column_paths {
|
||||
ret = ret.swap_data_by_column_path(
|
||||
path,
|
||||
Box::new(move |old| action(old, old.tag())),
|
||||
)?;
|
||||
}
|
||||
|
||||
ReturnSuccess::value(ret)
|
||||
}
|
||||
})
|
||||
.to_action_stream())
|
||||
}
|
||||
|
||||
pub fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||
let tag = tag.into();
|
||||
match &input.value {
|
||||
UntaggedValue::Primitive(prim) => Ok(UntaggedValue::binary(match prim {
|
||||
Primitive::Binary(b) => b.to_vec(),
|
||||
// TODO: Several places here we use Little Endian. We should probably
|
||||
// query the host to determine if it's Big Endian or Little Endian
|
||||
Primitive::Int(n_ref) => n_ref.to_bytes_le().1,
|
||||
Primitive::Decimal(dec) => match dec.to_bigint() {
|
||||
Some(n) => n.to_bytes_le().1,
|
||||
None => {
|
||||
return Err(ShellError::unimplemented(
|
||||
"failed to convert decimal to int",
|
||||
));
|
||||
}
|
||||
},
|
||||
Primitive::Filesize(a_filesize) => match a_filesize.to_bigint() {
|
||||
Some(n) => n.to_bytes_le().1,
|
||||
None => {
|
||||
return Err(ShellError::unimplemented(
|
||||
"failed to convert filesize to bigint",
|
||||
));
|
||||
}
|
||||
},
|
||||
Primitive::String(a_string) => a_string.as_bytes().to_vec(),
|
||||
Primitive::Boolean(a_bool) => match a_bool {
|
||||
false => BigInt::from(0).to_bytes_le().1,
|
||||
true => BigInt::from(1).to_bytes_le().1,
|
||||
},
|
||||
Primitive::Date(a_date) => a_date.format("%c").to_string().as_bytes().to_vec(),
|
||||
Primitive::FilePath(a_filepath) => a_filepath
|
||||
.as_path()
|
||||
.display()
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
_ => {
|
||||
return Err(ShellError::unimplemented(
|
||||
"'into int' for non-numeric primitives",
|
||||
))
|
||||
}
|
||||
})
|
||||
.into_value(&tag)),
|
||||
UntaggedValue::Row(_) => Err(ShellError::labeled_error(
|
||||
"specify column name to use, with 'into int COLUMN'",
|
||||
"found table",
|
||||
tag,
|
||||
)),
|
||||
_ => Err(ShellError::unimplemented("'into int' for unsupported type")),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::ShellError;
|
||||
use super::SubCommand;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() -> Result<(), ShellError> {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(SubCommand {})
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
mod binary;
|
||||
mod command;
|
||||
mod int;
|
||||
|
||||
pub use binary::SubCommand as IntoBinary;
|
||||
pub use command::Command as Into;
|
||||
pub use int::SubCommand as IntoInt;
|
||||
|
@ -435,7 +435,7 @@ fn html_value(value: &Value) -> String {
|
||||
output_string.push_str("\">");
|
||||
}
|
||||
_ => {
|
||||
let output = pretty_hex::pretty_hex(&b);
|
||||
let output = nu_pretty_hex::pretty_hex(&b);
|
||||
|
||||
output_string.push_str("<pre>");
|
||||
output_string.push_str(&output);
|
||||
@ -444,7 +444,7 @@ fn html_value(value: &Value) -> String {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let output = pretty_hex::pretty_hex(&b);
|
||||
let output = nu_pretty_hex::pretty_hex(&b);
|
||||
|
||||
output_string.push_str("<pre>");
|
||||
output_string.push_str(&output);
|
||||
|
Reference in New Issue
Block a user