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:
Darren Schroeder 2021-05-01 11:12:25 -05:00 committed by GitHub
parent a8f555856a
commit 8cd639f6a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 1256 additions and 31 deletions

97
Cargo.lock generated
View file

@ -183,6 +183,18 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "as-slice"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0"
dependencies = [
"generic-array 0.12.4",
"generic-array 0.13.3",
"generic-array 0.14.4",
"stable_deref_trait",
]
[[package]]
name = "async-channel"
version = "1.6.1"
@ -1967,6 +1979,24 @@ dependencies = [
"typenum",
]
[[package]]
name = "generic-array"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
dependencies = [
"typenum",
]
[[package]]
name = "generic-array"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309"
dependencies = [
"typenum",
]
[[package]]
name = "generic-array"
version = "0.14.4"
@ -2108,6 +2138,15 @@ dependencies = [
"regex 1.4.3",
]
[[package]]
name = "hash32"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
dependencies = [
"byteorder",
]
[[package]]
name = "hashbrown"
version = "0.9.1"
@ -2126,6 +2165,18 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "heapless"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "634bd4d29cbf24424d0a4bfcbf80c6960129dc24424752a7d1d1390607023422"
dependencies = [
"as-slice",
"generic-array 0.14.4",
"hash32",
"stable_deref_trait",
]
[[package]]
name = "heck"
version = "0.3.2"
@ -3107,6 +3158,15 @@ dependencies = [
"serial_test",
]
[[package]]
name = "nu-ansi-term"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bd69a141e8fdfa5ac882d8b816db2b9ad138ef7e3baa7cb753a9b3789aa8c7e"
dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "nu-ansi-term"
version = "0.30.1"
@ -3158,7 +3218,7 @@ dependencies = [
"lazy_static 1.4.0",
"log 0.4.14",
"meval",
"nu-ansi-term",
"nu-ansi-term 0.30.1",
"nu-command",
"nu-data",
"nu-engine",
@ -3166,6 +3226,7 @@ dependencies = [
"nu-json",
"nu-parser",
"nu-plugin",
"nu-pretty-hex",
"nu-protocol",
"nu-source",
"nu-stream",
@ -3177,7 +3238,6 @@ dependencies = [
"num-traits 0.2.14",
"parking_lot 0.11.1",
"pin-utils",
"pretty-hex",
"ptree",
"query_interface",
"quick-xml 0.21.0",
@ -3258,13 +3318,14 @@ dependencies = [
"md5 0.7.0",
"meval",
"minus",
"nu-ansi-term",
"nu-ansi-term 0.30.1",
"nu-data",
"nu-engine",
"nu-errors",
"nu-json",
"nu-parser",
"nu-plugin",
"nu-pretty-hex",
"nu-protocol",
"nu-source",
"nu-stream",
@ -3276,7 +3337,6 @@ dependencies = [
"num-traits 0.2.14",
"parking_lot 0.11.1",
"pin-utils",
"pretty-hex",
"ptree",
"query_interface",
"quick-xml 0.21.0",
@ -3331,7 +3391,7 @@ dependencies = [
"getset",
"indexmap",
"log 0.4.14",
"nu-ansi-term",
"nu-ansi-term 0.30.1",
"nu-errors",
"nu-protocol",
"nu-source",
@ -3375,7 +3435,7 @@ dependencies = [
"indexmap",
"itertools",
"log 0.4.14",
"nu-ansi-term",
"nu-ansi-term 0.30.1",
"nu-data",
"nu-errors",
"nu-parser",
@ -3410,7 +3470,7 @@ dependencies = [
"derive-new",
"getset",
"glob",
"nu-ansi-term",
"nu-ansi-term 0.30.1",
"nu-source",
"num-bigint 0.3.2",
"num-traits 0.2.14",
@ -3473,6 +3533,15 @@ dependencies = [
"serde_json",
]
[[package]]
name = "nu-pretty-hex"
version = "0.30.1"
dependencies = [
"heapless",
"nu-ansi-term 0.29.0",
"rand 0.8.3",
]
[[package]]
name = "nu-protocol"
version = "0.30.1"
@ -3521,7 +3590,7 @@ dependencies = [
name = "nu-table"
version = "0.30.1"
dependencies = [
"nu-ansi-term",
"nu-ansi-term 0.30.1",
"regex 1.4.3",
"unicode-width",
]
@ -3564,12 +3633,12 @@ dependencies = [
"crossterm 0.19.0",
"image 0.22.5",
"neso",
"nu-ansi-term",
"nu-ansi-term 0.30.1",
"nu-errors",
"nu-plugin",
"nu-pretty-hex",
"nu-protocol",
"nu-source",
"pretty-hex",
"rawkey",
]
@ -3755,7 +3824,7 @@ name = "nu_plugin_textview"
version = "0.30.1"
dependencies = [
"bat",
"nu-ansi-term",
"nu-ansi-term 0.30.1",
"nu-data",
"nu-errors",
"nu-plugin",
@ -4384,12 +4453,6 @@ dependencies = [
"typed-arena",
]
[[package]]
name = "pretty-hex"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5c99d529f0d30937f6f4b8a86d988047327bb88d04d2c4afc356de74722131"
[[package]]
name = "pretty_env_logger"
version = "0.4.0"

View file

@ -25,6 +25,7 @@ nu-table = { version = "0.30.1", path = "../nu-table" }
nu-test-support = { version = "0.30.1", path = "../nu-test-support" }
nu-value-ext = { version = "0.30.1", path = "../nu-value-ext" }
nu-ansi-term = { version = "0.30.1", path = "../nu-ansi-term" }
nu-pretty-hex = { version = "0.30.1", path = "../nu-pretty-hex" }
Inflector = "0.11"
arboard = { version = "1.1.0", optional = true }
@ -67,7 +68,6 @@ num-format = { version = "0.4.0", features = ["with-num-bigint"] }
num-traits = "0.2.14"
parking_lot = "0.11.1"
pin-utils = "0.1.0"
pretty-hex = "0.2.1"
ptree = { version = "0.3.1", optional = true }
query_interface = "0.3.5"
quick-xml = "0.21.0"

View file

@ -24,6 +24,7 @@ nu-table = { version = "0.30.1", path = "../nu-table" }
nu-test-support = { version = "0.30.1", path = "../nu-test-support" }
nu-value-ext = { version = "0.30.1", path = "../nu-value-ext" }
nu-ansi-term = { version = "0.30.1", path = "../nu-ansi-term" }
nu-pretty-hex = { version = "0.30.1", path = "../nu-pretty-hex" }
Inflector = "0.11"
arboard = { version = "1.1.0", optional = true }
@ -65,7 +66,6 @@ num-format = { version = "0.4.0", features = ["with-num-bigint"] }
num-traits = "0.2.14"
parking_lot = "0.11.1"
pin-utils = "0.1.0"
pretty-hex = "0.2.1"
ptree = { version = "0.3.1", optional = true }
query_interface = "0.3.5"
quick-xml = "0.21.0"

View file

@ -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;

View file

@ -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());
}
}

View file

@ -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

View 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 {})
}
}

View file

@ -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;

View file

@ -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);

201
crates/nu-pretty-hex/Cargo.lock generated Normal file
View file

@ -0,0 +1,201 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "as-slice"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45403b49e3954a4b8428a0ac21a4b7afadccf92bfd96273f1a58cd4812496ae0"
dependencies = [
"generic-array 0.12.4",
"generic-array 0.13.3",
"generic-array 0.14.4",
"stable_deref_trait",
]
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "generic-array"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
dependencies = [
"typenum",
]
[[package]]
name = "generic-array"
version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f797e67af32588215eaaab8327027ee8e71b9dd0b2b26996aedf20c030fce309"
dependencies = [
"typenum",
]
[[package]]
name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hash32"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4041af86e63ac4298ce40e5cca669066e75b6f1aa3390fe2561ffa5e1d9f4cc"
dependencies = [
"byteorder",
]
[[package]]
name = "heapless"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "634bd4d29cbf24424d0a4bfcbf80c6960129dc24424752a7d1d1390607023422"
dependencies = [
"as-slice",
"generic-array 0.14.4",
"hash32",
"stable_deref_trait",
]
[[package]]
name = "libc"
version = "0.2.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
[[package]]
name = "nu-ansi-term"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bd69a141e8fdfa5ac882d8b816db2b9ad138ef7e3baa7cb753a9b3789aa8c7e"
dependencies = [
"winapi",
]
[[package]]
name = "nu-pretty-hex"
version = "0.2.1"
dependencies = [
"heapless",
"nu-ansi-term",
"rand",
]
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "rand"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
dependencies = [
"rand_core",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "typenum"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
[[package]]
name = "version_check"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View file

@ -0,0 +1,30 @@
[package]
authors = [
"Andrei Volnin <wolandr@gmail.com>",
"The Nu Project Contributors"
]
description = "Pretty hex dump of bytes slice in the common style."
edition = "2018"
license = "MIT"
name = "nu-pretty-hex"
version = "0.30.1"
[lib]
doctest = false
name = "nu_pretty_hex"
path = "src/lib.rs"
[[bin]]
name = "nu_pretty_hex"
path = "src/main.rs"
[dependencies]
nu-ansi-term = "0.29.0"
rand = "0.8.3"
[dev-dependencies]
heapless = "0.6.1"
# [features]
# default = ["alloc"]
# alloc = []

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Andrei Volnin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,81 @@
# nu-pretty-hex
An update of prett-hex to make it prettier
[![crates.io](https://img.shields.io/crates/v/pretty-hex.svg)](https://crates.io/crates/pretty-hex)
[![docs.rs](https://docs.rs/pretty-hex/badge.svg)](https://docs.rs/pretty-hex)
A Rust library providing pretty hex dump.
A `simple_hex()` way renders one-line hex dump, a `pretty_hex()` way renders
columned multi-line hex dump with addressing and ASCII representation.
A `config_hex()` way renders hex dump in specified format.
## Inspiration
[Hexed](https://github.com/adolfohw/hexed) \
[Hexyl](https://github.com/sharkdp/hexyl) \
[Pretty-hex](https://github.com/wolandr/pretty-hex)
## Example of `simple_hex()`
```rust
use pretty_hex::*;
let v = vec![222, 173, 190, 239, 202, 254, 32, 24];
assert_eq!(simple_hex(&v), format!("{}", v.hex_dump()));
println!("{}", v.hex_dump());
```
Output:
```text
de ad be ef ca fe 20 18
```
## Example of `pretty_hex()`
```rust
use pretty_hex::*;
let v: &[u8] = &random::<[u8;30]>();
assert_eq!(pretty_hex(&v), format!("{:?}", v.hex_dump()));
println!("{:?}", v.hex_dump());
```
Output:
```text
Length: 30 (0x1e) bytes
0000: 6b 4e 1a c3 af 03 d2 1e 7e 73 ba c8 bd 84 0f 83 kN......~s......
0010: 89 d5 cf 90 23 67 4b 48 db b1 bc 35 bf ee ....#gKH...5..
```
## Example of `config_hex()`
```rust
use pretty_hex::*;
let cfg = HexConfig {title: false, width: 8, group: 0, ..HexConfig::default() };
let v = &include_bytes!("data");
assert_eq!(config_hex(&v, cfg), format!("{:?}", v.hex_conf(cfg)));
println!("{:?}", v.hex_conf(cfg));
```
Output:
```text
0000: 6b 4e 1a c3 af 03 d2 1e kN......
0008: 7e 73 ba c8 bd 84 0f 83 ~s......
0010: 89 d5 cf 90 23 67 4b 48 ....#gKH
0018: db b1 bc 35 bf ee ...5..
```
---
Inspired by [haskell's pretty-hex](https://hackage.haskell.org/package/pretty-hex-1.0).

View file

@ -0,0 +1,66 @@
// #![no_std]
//! A Rust library providing pretty hex dump.
//!
//! A `simple_hex()` way renders one-line hex dump, and a `pretty_hex()` way renders
//! columned multi-line hex dump with addressing and ASCII representation.
//! A `config_hex()` way renders hex dump in specified format.
//!
//! ## Example of `simple_hex()`
//! ```
//! use pretty_hex::*;
//!
//! let v = vec![222, 173, 190, 239, 202, 254, 32, 24];
//! # #[cfg(feature = "alloc")]
//! assert_eq!(simple_hex(&v), format!("{}", v.hex_dump()));
//!
//! println!("{}", v.hex_dump());
//! ```
//! Output:
//!
//! ```text
//! de ad be ef ca fe 20 18
//! ```
//! ## Example of `pretty_hex()`
//! ```
//! use pretty_hex::*;
//!
//! let v = &include_bytes!("../tests/data");
//! # #[cfg(feature = "alloc")]
//! assert_eq!(pretty_hex(&v), format!("{:?}", v.hex_dump()));
//!
//! println!("{:?}", v.hex_dump());
//! ```
//! Output:
//!
//! ```text
//! Length: 30 (0x1e) bytes
//! 0000: 6b 4e 1a c3 af 03 d2 1e 7e 73 ba c8 bd 84 0f 83 kN......~s......
//! 0010: 89 d5 cf 90 23 67 4b 48 db b1 bc 35 bf ee ....#gKH...5..
//! ```
//! ## Example of `config_hex()`
//! ```
//! use pretty_hex::*;
//!
//! let cfg = HexConfig {title: false, width: 8, group: 0, ..HexConfig::default() };
//!
//! let v = &include_bytes!("../tests/data");
//! # #[cfg(feature = "alloc")]
//! assert_eq!(config_hex(&v, cfg), format!("{:?}", v.hex_conf(cfg)));
//!
//! println!("{:?}", v.hex_conf(cfg));
//! ```
//! Output:
//!
//! ```text
//! 0000: 6b 4e 1a c3 af 03 d2 1e kN......
//! 0008: 7e 73 ba c8 bd 84 0f 83 ~s......
//! 0010: 89 d5 cf 90 23 67 4b 48 ....#gKH
//! 0018: db b1 bc 35 bf ee ...5..
//! ```
#[cfg(feature = "alloc")]
extern crate alloc;
mod pretty_hex;
pub use pretty_hex::*;

View file

@ -0,0 +1,50 @@
use nu_pretty_hex::*;
fn main() {
let config = HexConfig {
title: true,
ascii: true,
width: 16,
group: 4,
chunk: 1,
skip: Some(10),
// length: Some(5),
// length: None,
length: Some(50),
};
let my_string = "Darren Schroeder 😉";
println!("ConfigHex\n{}\n", config_hex(&my_string, config));
println!("SimpleHex\n{}\n", simple_hex(&my_string));
println!("PrettyHex\n{}\n", pretty_hex(&my_string));
println!("ConfigHex\n{}\n", config_hex(&my_string, config));
// let mut my_str = String::new();
// for x in 0..256 {
// my_str.push(x as u8);
// }
let mut v: Vec<u8> = vec![];
for x in 0..=127 {
v.push(x);
}
let my_str = String::from_utf8_lossy(&v[..]);
println!("First128\n{}\n", pretty_hex(&my_str.as_bytes()));
println!(
"First128-Param\n{}\n",
config_hex(&my_str.as_bytes(), config)
);
let mut r_str = String::new();
for _ in 0..=127 {
r_str.push(rand::random::<u8>() as char);
}
println!("Random127\n{}\n", pretty_hex(&r_str));
}
//chunk 0 44617272656e20536368726f65646572 Darren Schroeder
//chunk 1 44 61 72 72 65 6e 20 53 63 68 72 6f 65 64 65 72 Darren Schroeder
//chunk 2 461 7272 656e 2053 6368 726f 6564 6572 Darren Schroeder
//chunk 3 46172 72656e 205363 68726f 656465 72 Darren Schroeder
//chunk 4 44617272 656e2053 6368726f 65646572 Darren Schroeder

View file

@ -0,0 +1,305 @@
use core::primitive::str;
use core::{default::Default, fmt};
use nu_ansi_term::{Color, Style};
/// Returns a one-line hexdump of `source` grouped in default format without header
/// and ASCII column.
pub fn simple_hex<T: AsRef<[u8]>>(source: &T) -> String {
let mut writer = String::new();
hex_write(&mut writer, source, HexConfig::simple(), None).unwrap_or(());
writer
}
/// Dump `source` as hex octets in default format without header and ASCII column to the `writer`.
pub fn simple_hex_write<T, W>(writer: &mut W, source: &T) -> fmt::Result
where
T: AsRef<[u8]>,
W: fmt::Write,
{
hex_write(writer, source, HexConfig::simple(), None)
}
/// Return a multi-line hexdump in default format complete with addressing, hex digits,
/// and ASCII representation.
pub fn pretty_hex<T: AsRef<[u8]>>(source: &T) -> String {
let mut writer = String::new();
hex_write(&mut writer, source, HexConfig::default(), Some(true)).unwrap_or(());
writer
}
/// Write multi-line hexdump in default format complete with addressing, hex digits,
/// and ASCII representation to the writer.
pub fn pretty_hex_write<T, W>(writer: &mut W, source: &T) -> fmt::Result
where
T: AsRef<[u8]>,
W: fmt::Write,
{
hex_write(writer, source, HexConfig::default(), Some(true))
}
/// Return a hexdump of `source` in specified format.
pub fn config_hex<T: AsRef<[u8]>>(source: &T, cfg: HexConfig) -> String {
let mut writer = String::new();
hex_write(&mut writer, source, cfg, Some(true)).unwrap_or(());
writer
}
/// Configuration parameters for hexdump.
#[derive(Clone, Copy, Debug)]
pub struct HexConfig {
/// Write first line header with data length.
pub title: bool,
/// Append ASCII representation column.
pub ascii: bool,
/// Source bytes per row. 0 for single row without address prefix.
pub width: usize,
/// Chunks count per group. 0 for single group (column).
pub group: usize,
/// Source bytes per chunk (word). 0 for single word.
pub chunk: usize,
/// Bytes from 0 to skip
pub skip: Option<usize>,
/// Length to return
pub length: Option<usize>,
}
/// Default configuration with `title`, `ascii`, 16 source bytes `width` grouped to 4 separate
/// hex bytes. Using in `pretty_hex`, `pretty_hex_write` and `fmt::Debug` implementation.
impl Default for HexConfig {
fn default() -> HexConfig {
HexConfig {
title: true,
ascii: true,
width: 16,
group: 4,
chunk: 1,
skip: None,
length: None,
}
}
}
impl HexConfig {
/// Returns configuration for `simple_hex`, `simple_hex_write` and `fmt::Display` implementation.
pub fn simple() -> Self {
HexConfig::default().to_simple()
}
fn delimiter(&self, i: usize) -> &'static str {
if i > 0 && self.chunk > 0 && i % self.chunk == 0 {
if self.group > 0 && i % (self.group * self.chunk) == 0 {
" "
} else {
" "
}
} else {
""
}
}
fn to_simple(self) -> Self {
HexConfig {
title: false,
ascii: false,
width: 0,
..self
}
}
}
fn categorize_byte(byte: &u8) -> (Style, Option<char>) {
// This section is here so later we can configure these items
let null_char_style = Style::default().fg(Color::Fixed(242));
let null_char = Some('0');
let ascii_printable_style = Style::default().fg(Color::Cyan).bold();
let ascii_printable = None;
let ascii_space_style = Style::default().fg(Color::Green).bold();
let ascii_space = Some(' ');
let ascii_white_space_style = Style::default().fg(Color::Green).bold();
let ascii_white_space = Some('_');
let ascii_other_style = Style::default().fg(Color::Purple).bold();
let ascii_other = Some('•');
let non_ascii_style = Style::default().fg(Color::Yellow).bold();
let non_ascii = Some('×'); // or Some('.')
if byte == &0 {
(null_char_style, null_char)
} else if byte.is_ascii_graphic() {
(ascii_printable_style, ascii_printable)
} else if byte.is_ascii_whitespace() {
// 0x20 == 32 decimal - replace with a real space
if byte == &32 {
(ascii_space_style, ascii_space)
} else {
(ascii_white_space_style, ascii_white_space)
}
} else if byte.is_ascii() {
(ascii_other_style, ascii_other)
} else {
(non_ascii_style, non_ascii)
}
}
/// Write hex dump in specified format.
pub fn hex_write<T, W>(
writer: &mut W,
source: &T,
cfg: HexConfig,
with_color: Option<bool>,
) -> fmt::Result
where
T: AsRef<[u8]>,
W: fmt::Write,
{
let use_color = with_color.unwrap_or(false);
if source.as_ref().is_empty() {
return Ok(());
}
let amount = match cfg.length {
Some(len) => len,
None => source.as_ref().len(),
};
let skip = cfg.skip.unwrap_or(0);
let source_part_vec: Vec<u8> = source
.as_ref()
.iter()
.skip(skip)
.take(amount)
.map(|x| *x as u8)
.collect();
let source_part = String::from_utf8_lossy(&source_part_vec[..]);
if cfg.title {
if use_color {
writeln!(
writer,
"Length: {0} (0x{0:x}) bytes | {1}printable {2}whitespace {3}ascii_other {4}non_ascii{5}",
source_part.as_bytes().as_ref().len(),
Style::default().fg(Color::Cyan).bold().prefix(),
Style::default().fg(Color::Green).bold().prefix(),
Style::default().fg(Color::Purple).bold().prefix(),
Style::default().fg(Color::Yellow).bold().prefix(),
Style::default().fg(Color::Yellow).suffix()
)?;
} else {
writeln!(
writer,
"Length: {0} (0x{0:x}) bytes",
source_part.as_bytes().as_ref().len(),
)?;
}
}
let lines = source_part.as_bytes().as_ref().chunks(if cfg.width > 0 {
cfg.width
} else {
source_part.as_bytes().as_ref().len()
});
let lines_len = lines.len();
for (i, row) in lines.enumerate() {
if cfg.width > 0 {
let style = Style::default().fg(Color::Cyan);
if use_color {
write!(
writer,
"{}{:08x}{}: ",
style.prefix(),
i * cfg.width + skip,
style.suffix()
)?;
} else {
write!(writer, "{:08x}: ", i * cfg.width + skip,)?;
}
}
for (i, x) in row.as_ref().iter().enumerate() {
if use_color {
let (style, _char) = categorize_byte(x);
write!(
writer,
"{}{}{:02x}{}",
cfg.delimiter(i),
style.prefix(),
x,
style.suffix()
)?;
} else {
write!(writer, "{}{:02x}", cfg.delimiter(i), x,)?;
}
}
if cfg.ascii {
for j in row.len()..cfg.width {
write!(writer, "{} ", cfg.delimiter(j))?;
}
write!(writer, " ")?;
for x in row {
let (style, a_char) = categorize_byte(x);
let replacement_char = match a_char {
Some(c) => c,
None => *x as char,
};
if use_color {
write!(
writer,
"{}{}{}",
style.prefix(),
replacement_char,
style.suffix()
)?;
} else {
write!(writer, "{}", replacement_char,)?;
}
}
}
if i + 1 < lines_len {
writeln!(writer)?;
}
}
Ok(())
}
/// Reference wrapper for use in arguments formatting.
pub struct Hex<'a, T: 'a>(&'a T, HexConfig);
impl<'a, T: 'a + AsRef<[u8]>> fmt::Display for Hex<'a, T> {
/// Formats the value by `simple_hex_write` using the given formatter.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
hex_write(f, self.0, self.1.to_simple(), None)
}
}
impl<'a, T: 'a + AsRef<[u8]>> fmt::Debug for Hex<'a, T> {
/// Formats the value by `pretty_hex_write` using the given formatter.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
hex_write(f, self.0, self.1, None)
}
}
/// Allows generates hex dumps to a formatter.
pub trait PrettyHex: Sized {
/// Wrap self reference for use in `std::fmt::Display` and `std::fmt::Debug`
/// formatting as hex dumps.
fn hex_dump(&self) -> Hex<Self>;
/// Wrap self reference for use in `std::fmt::Display` and `std::fmt::Debug`
/// formatting as hex dumps in specified format.
fn hex_conf(&self, cfg: HexConfig) -> Hex<Self>;
}
impl<T> PrettyHex for T
where
T: AsRef<[u8]>,
{
fn hex_dump(&self) -> Hex<Self> {
Hex(self, HexConfig::default())
}
fn hex_conf(&self, cfg: HexConfig) -> Hex<Self> {
Hex(self, cfg)
}
}

View file

@ -0,0 +1,17 @@
Length: 256 (0x100) bytes
0000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................
0010: 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................
0020: 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f !"#$%&'()*+,-./
0030: 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?
0040: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO
0050: 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f PQRSTUVWXYZ[\]^_
0060: 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f `abcdefghijklmno
0070: 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f pqrstuvwxyz{|}~.
0080: 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f ................
0090: 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f ................
00a0: a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af ................
00b0: b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf ................
00c0: c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf ................
00d0: d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df ................
00e0: e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef ................
00f0: f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff ................

View file

@ -0,0 +1 @@
kNУЏв~sКШН<D0A8><0F><>еЯ<D0B5>#gKHлБМ5Пю

View file

@ -0,0 +1,175 @@
// #![no_std]
#[cfg(feature = "alloc")]
extern crate alloc;
extern crate nu_pretty_hex;
#[cfg(feature = "alloc")]
use alloc::{format, string::String, vec, vec::Vec};
use nu_pretty_hex::*;
#[cfg(feature = "alloc")]
#[test]
fn test_simple() {
let bytes: Vec<u8> = (0..16).collect();
let expected = "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f";
assert_eq!(expected, simple_hex(&bytes));
assert_eq!(expected, format!("{}", bytes.hex_dump()));
assert_eq!(simple_hex(&bytes), config_hex(&bytes, HexConfig::simple()));
let mut have = String::new();
simple_hex_write(&mut have, &bytes).unwrap();
assert_eq!(expected, have);
let str = "string";
let string: String = String::from("string");
let slice: &[u8] = &[0x73, 0x74, 0x72, 0x69, 0x6e, 0x67];
assert_eq!(simple_hex(&str), "73 74 72 69 6e 67");
assert_eq!(simple_hex(&str), simple_hex(&string));
assert_eq!(simple_hex(&str), simple_hex(&slice));
assert!(simple_hex(&vec![]).is_empty());
}
#[cfg(feature = "alloc")]
#[test]
fn test_pretty() {
let bytes: Vec<u8> = (0..256).map(|x| x as u8).collect();
let want = include_str!("256.txt");
let mut hex = String::new();
pretty_hex_write(&mut hex, &bytes).unwrap();
assert_eq!(want, hex);
assert_eq!(want, format!("{:?}", bytes.hex_dump()));
assert_eq!(want, pretty_hex(&bytes));
assert_eq!(want, config_hex(&bytes, HexConfig::default()));
assert_eq!("Length: 0 (0x0) bytes\n", pretty_hex(&vec![]));
}
#[cfg(feature = "alloc")]
#[test]
fn test_config() {
let cfg = HexConfig {
title: false,
ascii: false,
width: 0,
group: 0,
chunk: 0,
};
assert!(config_hex(&vec![], cfg).is_empty());
assert_eq!("2425262728", config_hex(&"$%&'(", cfg));
let v = include_bytes!("data");
let cfg = HexConfig {
title: false,
group: 8,
..HexConfig::default()
};
let hex = "0000: 6b 4e 1a c3 af 03 d2 1e 7e 73 ba c8 bd 84 0f 83 kN......~s......\n\
0010: 89 d5 cf 90 23 67 4b 48 db b1 bc 35 bf ee ....#gKH...5..";
assert_eq!(hex, config_hex(&v, cfg));
assert_eq!(hex, format!("{:?}", v.hex_conf(cfg)));
let mut str = String::new();
hex_write(&mut str, v, cfg).unwrap();
assert_eq!(hex, str);
assert_eq!(
config_hex(
&v,
HexConfig {
ascii: false,
..cfg
}
),
"0000: 6b 4e 1a c3 af 03 d2 1e 7e 73 ba c8 bd 84 0f 83\n\
0010: 89 d5 cf 90 23 67 4b 48 db b1 bc 35 bf ee"
);
assert_eq!(
config_hex(
&v,
HexConfig {
ascii: false,
group: 4,
chunk: 2,
..cfg
}
),
"0000: 6b4e 1ac3 af03 d21e 7e73 bac8 bd84 0f83\n\
0010: 89d5 cf90 2367 4b48 dbb1 bc35 bfee"
);
let v: Vec<u8> = (0..21).collect();
let want = r##"Length: 21 (0x15) bytes
0000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................
0010: 10 11 12 13 14 ....."##;
assert_eq!(want, pretty_hex(&v));
let v: Vec<u8> = (0..13).collect();
assert_eq!(
config_hex(
&v,
HexConfig {
title: false,
ascii: true,
width: 11,
group: 2,
chunk: 3
}
),
"0000: 000102 030405 060708 090a ...........\n\
000b: 0b0c .."
);
let v: Vec<u8> = (0..19).collect();
assert_eq!(
config_hex(
&v,
HexConfig {
title: false,
ascii: true,
width: 16,
group: 3,
chunk: 3
}
),
"0000: 000102 030405 060708 090a0b 0c0d0e 0f ................\n\
0010: 101112 ..."
);
let cfg = HexConfig {
title: false,
group: 0,
..HexConfig::default()
};
assert_eq!(
format!("{:?}", v.hex_conf(cfg)),
"0000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................\n\
0010: 10 11 12 ..."
);
assert_eq!(
format!("{}", v.hex_conf(cfg)),
"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12"
);
}
// This test case checks that hex_write works even without the alloc crate.
// Decorators to this function like simple_hex_write or PrettyHex::hex_dump()
// will be tested when the alloc feature is selected because it feels quite
// cumbersome to set up these tests without the comodity from `alloc`.
#[test]
fn test_hex_write_with_simple_config() {
let config = HexConfig::simple();
let bytes = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
let expected =
core::str::from_utf8(b"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f").unwrap();
// let expected =
// "\u{1b}[38;5;242m00\u{1b}[0m \u{1b}[1;35m01\u{1b}[0m \u{1b}[1;35m02\u{1b}[0m \u{1b}[1;";
let mut buffer = heapless::Vec::<u8, heapless::consts::U50>::new();
hex_write(&mut buffer, &bytes, config, None).unwrap();
let have = core::str::from_utf8(&buffer).unwrap();
assert_eq!(expected, have);
}

View file

@ -18,7 +18,7 @@ nu-plugin = { path = "../nu-plugin", version = "0.30.1" }
nu-protocol = { path = "../nu-protocol", version = "0.30.1" }
nu-source = { path = "../nu-source", version = "0.30.1" }
nu-ansi-term = { version = "0.30.1", path = "../nu-ansi-term" }
pretty-hex = "0.2.1"
nu-pretty-hex = { version = "0.30.1", path = "../nu-pretty-hex" }
rawkey = "0.1.3"
[build-dependencies]

View file

@ -1,7 +1,7 @@
use crossterm::{style::Attribute, ExecutableCommand};
use nu_protocol::outln;
use nu_pretty_hex::*;
use nu_protocol::{outln, Value};
use nu_source::AnchorLocation;
use pretty_hex::*;
#[derive(Default)]
pub struct BinaryView;
@ -16,6 +16,8 @@ pub fn view_binary(
b: &[u8],
source: Option<&AnchorLocation>,
lores_mode: bool,
skip: Option<&Value>,
length: Option<&Value>,
) -> Result<(), Box<dyn std::error::Error>> {
if b.len() > 3 {
if let (0x4e, 0x45, 0x53) = (b[0], b[1], b[2]) {
@ -23,7 +25,8 @@ pub fn view_binary(
return Ok(());
}
}
view_contents(b, source, lores_mode)?;
view_contents(b, source, lores_mode, skip, length)?;
Ok(())
}
@ -207,7 +210,29 @@ pub fn view_contents(
buffer: &[u8],
_source: Option<&AnchorLocation>,
lores_mode: bool,
skip: Option<&Value>,
length: Option<&Value>,
) -> Result<(), Box<dyn std::error::Error>> {
let skip_bytes = match skip {
Some(s) => Some(s.as_usize().unwrap_or(0)),
None => None,
};
let num_bytes = match length {
Some(b) => Some(b.as_usize().unwrap_or(0)),
None => None,
};
let config = HexConfig {
title: true,
ascii: true,
width: 16,
group: 4,
chunk: 1,
skip: skip_bytes,
length: num_bytes,
};
let mut raw_image_buffer = load_from_png_buffer(buffer);
if raw_image_buffer.is_err() {
@ -216,7 +241,7 @@ pub fn view_contents(
if raw_image_buffer.is_err() {
//Not yet supported
outln!("{:?}", buffer.hex_dump());
outln!("{}", config_hex(&buffer, config));
return Ok(());
}
let raw_image_buffer = raw_image_buffer?;
@ -270,7 +295,8 @@ pub fn view_contents(
}
_ => {
//Not yet supported
outln!("{:?}", buffer.hex_dump());
// outln!("{:?}", buffer.hex_dump());
outln!("{}", config_hex(&buffer, config));
return Ok(());
}
}

View file

@ -1,6 +1,6 @@
use nu_errors::ShellError;
use nu_plugin::Plugin;
use nu_protocol::{CallInfo, Primitive, Signature, UntaggedValue, Value};
use nu_protocol::{CallInfo, Primitive, Signature, SyntaxShape, UntaggedValue, Value};
use crate::binaryview::view_binary;
use crate::BinaryView;
@ -9,14 +9,29 @@ impl Plugin for BinaryView {
fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("binaryview")
.desc("Autoview of binary data.")
.switch("lores", "use low resolution output mode", Some('l')))
.switch("lores", "use low resolution output mode", Some('l'))
.named(
"skip",
SyntaxShape::Int,
"skip x number of bytes",
Some('s'),
)
.named(
"bytes",
SyntaxShape::Int,
"show y number of bytes",
Some('b'),
))
}
fn sink(&mut self, call_info: CallInfo, input: Vec<Value>) {
for v in input {
let value_anchor = v.anchor();
if let UntaggedValue::Primitive(Primitive::Binary(b)) = &v.value {
let _ = view_binary(&b, value_anchor.as_ref(), call_info.args.has("lores"));
let low_res = call_info.args.has("lores");
let skip = call_info.args.get("skip");
let length = call_info.args.get("bytes");
let _ = view_binary(&b, value_anchor.as_ref(), low_res, skip, length);
}
}
}