mirror of
https://github.com/nushell/nushell
synced 2024-12-26 13:03:07 +00:00
Port hash
, hash md5
and hash sha256
commands (#464)
`hash` by itself is only printing the help message. The other two are simply using the same generic implementation.
This commit is contained in:
parent
95841e3489
commit
e77c6bb284
10 changed files with 408 additions and 49 deletions
148
Cargo.lock
generated
148
Cargo.lock
generated
|
@ -93,9 +93,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.48"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62e1f47f7dc0422027a4e370dd4548d4d66b26782e513e98dca1e689e058a80e"
|
||||
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
|
@ -200,9 +200,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.51"
|
||||
version = "0.1.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e"
|
||||
checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -282,6 +282,15 @@ dependencies = [
|
|||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1d36a02058e76b040de25a4464ba1c80935655595b661505c8b39b664828b95"
|
||||
dependencies = [
|
||||
"generic-array 0.14.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotli"
|
||||
version = "3.3.2"
|
||||
|
@ -443,9 +452,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "chrono-tz"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64c01c1c607d25c71bbaa67c113d6c6b36c434744b4fd66691d711b5b1bc0c8b"
|
||||
checksum = "58549f1842da3080ce63002102d5bc954c7bc843d4f47818e642abdc36253552"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"chrono-tz-build",
|
||||
|
@ -500,10 +509,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.2"
|
||||
name = "cpufeatures"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3825b1e8580894917dc4468cb634a1b4e9745fddc854edad72d9c04644c0319f"
|
||||
checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
@ -584,6 +602,15 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567569e659735adb39ff2d4c20600f7cd78be5471f8c58ab162bce3c03fdbc5f"
|
||||
dependencies = [
|
||||
"generic-array 0.14.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cstr_core"
|
||||
version = "0.2.4"
|
||||
|
@ -666,6 +693,17 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8549e6bfdecd113b7e221fe60b433087f6957387a20f8118ebca9b12af19143d"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
"generic-array 0.14.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "1.0.5"
|
||||
|
@ -772,9 +810,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
|||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.29"
|
||||
version = "0.8.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746"
|
||||
checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
@ -1020,9 +1058,9 @@ checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
|
|||
|
||||
[[package]]
|
||||
name = "git2"
|
||||
version = "0.13.24"
|
||||
version = "0.13.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "845e007a28f1fcac035715988a234e8ec5458fd825b20a20c7dec74237ef341f"
|
||||
checksum = "f29229cc1b24c0e6062f6e742aa3e256492a5323365e5ed3413599f8a5eff7d6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
|
@ -1173,9 +1211,9 @@ checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb"
|
|||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.1"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf"
|
||||
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
@ -1285,15 +1323,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.108"
|
||||
version = "0.2.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
|
||||
checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01"
|
||||
|
||||
[[package]]
|
||||
name = "libgit2-sys"
|
||||
version = "0.12.25+1.3.0"
|
||||
version = "0.12.26+1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f68169ef08d6519b2fe133ecc637408d933c0174b23b80bb2f79828966fbaab"
|
||||
checksum = "19e1c899248e606fbfe68dcb31d8b0176ebab833b103824af31bddf4b7457494"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
|
@ -1393,6 +1431,15 @@ version = "0.1.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6a38fc55c8bbc10058782919516f88826e70320db6d206aebc49611d24216ae"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
|
@ -1410,9 +1457,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.4"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
@ -1594,14 +1641,16 @@ name = "nu-command"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"base64",
|
||||
"bytesize",
|
||||
"calamine",
|
||||
"chrono",
|
||||
"chrono-humanize",
|
||||
"chrono-tz 0.6.0",
|
||||
"chrono-tz 0.6.1",
|
||||
"crossterm",
|
||||
"csv",
|
||||
"dialoguer",
|
||||
"digest",
|
||||
"dtparse",
|
||||
"eml-parser",
|
||||
"glob",
|
||||
|
@ -1611,6 +1660,7 @@ dependencies = [
|
|||
"itertools",
|
||||
"lazy_static",
|
||||
"lscolors",
|
||||
"md-5",
|
||||
"meval",
|
||||
"nu-ansi-term 0.39.0",
|
||||
"nu-engine",
|
||||
|
@ -1633,6 +1683,7 @@ dependencies = [
|
|||
"serde_ini",
|
||||
"serde_urlencoded",
|
||||
"serde_yaml",
|
||||
"sha2",
|
||||
"strip-ansi-escapes",
|
||||
"sysinfo",
|
||||
"terminal_size",
|
||||
|
@ -2013,9 +2064,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "parquet2"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41051fae4c0fab9040e291b360c6c8037d09d482aa83e94e37f3d080a32a58c3"
|
||||
checksum = "57e98d7da0076cead49c49580cc5771dfe0ba8a93cadff9b47c1681a4a78e1f9"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"bitpacking",
|
||||
|
@ -2106,9 +2157,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.22"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
|
||||
checksum = "d1a3ea4f0dd7f1f3e512cf97bf100819aa547f36a6eccac8dbaae839eb92363e"
|
||||
|
||||
[[package]]
|
||||
name = "polars"
|
||||
|
@ -2262,9 +2313,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.32"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
|
||||
checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
@ -2539,9 +2590,9 @@ checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
|||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
|
@ -2578,18 +2629,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.130"
|
||||
version = "1.0.131"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
|
||||
checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.130"
|
||||
version = "1.0.131"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
|
||||
checksum = "b710a83c4e0dff6a3d511946b95274ad9ca9e5d3ae497b63fda866ac955358d2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2609,9 +2660,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.71"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19"
|
||||
checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
|
@ -2621,9 +2672,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_test"
|
||||
version = "1.0.130"
|
||||
version = "1.0.131"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d82178225dbdeae2d5d190e8649287db6a3a32c6d24da22ae3146325aa353e4c"
|
||||
checksum = "dfaa01d46254ba300fb5920e781e9eae209daac68b68b26cdd678da7bd4fc5c4"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
@ -2653,10 +2704,21 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.10"
|
||||
name = "sha2"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1"
|
||||
checksum = "900d964dd36bb15bcf2f2b35694c072feab74969a54f2bbeec7a2d725d2bdcb6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c35dfd12afb7828318348b8c408383cf5071a086c1d4ab1c0f9840ec92dbb922"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
|
@ -2800,9 +2862,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.81"
|
||||
version = "1.0.82"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
|
||||
checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -57,8 +57,12 @@ lazy_static = "1.4.0"
|
|||
strip-ansi-escapes = "0.1.1"
|
||||
crossterm = "0.22.1"
|
||||
quick-xml = "0.22"
|
||||
digest = "0.10.0"
|
||||
md5 = { package = "md-5", version = "0.10.0" }
|
||||
sha2 = "0.10.0"
|
||||
base64 = "0.13.0"
|
||||
|
||||
num = {version="0.4.0", optional=true}
|
||||
num = { version = "0.4.0", optional = true }
|
||||
|
||||
[dependencies.polars]
|
||||
version = "0.18.0"
|
||||
|
|
|
@ -9,10 +9,7 @@ pub fn create_default_context() -> EngineState {
|
|||
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||
|
||||
macro_rules! bind_command {
|
||||
( $command:expr ) => {
|
||||
working_set.add_decl(Box::new($command));
|
||||
};
|
||||
( $( $command:expr ),* ) => {
|
||||
( $( $command:expr ),* $(,)? ) => {
|
||||
$( working_set.add_decl(Box::new($command)); )*
|
||||
};
|
||||
}
|
||||
|
@ -175,7 +172,11 @@ pub fn create_default_context() -> EngineState {
|
|||
Where,
|
||||
WithEnv,
|
||||
Wrap,
|
||||
Zip
|
||||
Zip,
|
||||
// Hash
|
||||
Hash,
|
||||
HashMd5::default(),
|
||||
HashSha256::default(),
|
||||
);
|
||||
|
||||
#[cfg(feature = "plugin")]
|
||||
|
|
35
crates/nu-command/src/hash/command.rs
Normal file
35
crates/nu-command/src/hash/command.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use nu_engine::get_full_help;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Category, IntoPipelineData, PipelineData, ShellError, Signature, Value};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Hash;
|
||||
|
||||
impl Command for Hash {
|
||||
fn name(&self) -> &str {
|
||||
"hash"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("hash").category(Category::Hash)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Apply hash function."
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
_stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
Ok(Value::String {
|
||||
val: get_full_help(&Self.signature(), &Self.examples(), engine_state),
|
||||
span: call.head,
|
||||
}
|
||||
.into_pipeline_data())
|
||||
}
|
||||
}
|
108
crates/nu-command/src/hash/generic_digest.rs
Normal file
108
crates/nu-command/src/hash/generic_digest.rs
Normal file
|
@ -0,0 +1,108 @@
|
|||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::{Call, CellPath};
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub trait HashDigest: digest::Digest + Clone {
|
||||
fn name() -> &'static str;
|
||||
fn examples() -> Vec<Example>;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GenericDigest<D: HashDigest> {
|
||||
name: String,
|
||||
usage: String,
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D: HashDigest> Default for GenericDigest<D> {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: format!("hash {}", D::name()),
|
||||
usage: format!("hash a value using the {} hash algorithm", D::name()),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D> Command for GenericDigest<D>
|
||||
where
|
||||
D: HashDigest + Send + Sync + 'static,
|
||||
digest::Output<D>: core::fmt::LowerHex,
|
||||
{
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build(self.name()).rest(
|
||||
"rest",
|
||||
SyntaxShape::CellPath,
|
||||
format!("optionally {} hash data by cell path", D::name()),
|
||||
)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
&self.usage
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
D::examples()
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
||||
let cell_paths: Vec<CellPath> = call.rest(engine_state, stack, 0)?;
|
||||
|
||||
input.map(
|
||||
move |v| {
|
||||
if cell_paths.is_empty() {
|
||||
action::<D>(&v)
|
||||
} else {
|
||||
let mut v = v;
|
||||
for path in &cell_paths {
|
||||
let ret = v
|
||||
.update_cell_path(&path.members, Box::new(move |old| action::<D>(old)));
|
||||
if let Err(error) = ret {
|
||||
return Value::Error { error };
|
||||
}
|
||||
}
|
||||
v
|
||||
}
|
||||
},
|
||||
engine_state.ctrlc.clone(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn action<D>(input: &Value) -> Value
|
||||
where
|
||||
D: HashDigest,
|
||||
digest::Output<D>: core::fmt::LowerHex,
|
||||
{
|
||||
let (bytes, span) = match input {
|
||||
Value::String { val, span } => (val.as_bytes(), *span),
|
||||
Value::Binary { val, span } => (val.as_slice(), *span),
|
||||
other => {
|
||||
return Value::Error {
|
||||
error: ShellError::UnsupportedInput(
|
||||
format!(
|
||||
"Type `{}` is not supported for {} hashing input",
|
||||
other.get_type(),
|
||||
D::name()
|
||||
),
|
||||
input.span().unwrap_or_else(|_| Span::unknown()),
|
||||
),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
let val = format!("{:x}", D::digest(bytes));
|
||||
Value::String { val, span }
|
||||
}
|
68
crates/nu-command/src/hash/md5.rs
Normal file
68
crates/nu-command/src/hash/md5.rs
Normal file
|
@ -0,0 +1,68 @@
|
|||
use super::generic_digest::{GenericDigest, HashDigest};
|
||||
use ::md5::Md5;
|
||||
use nu_protocol::{Example, Span, Value};
|
||||
|
||||
pub type HashMd5 = GenericDigest<Md5>;
|
||||
|
||||
impl HashDigest for Md5 {
|
||||
fn name() -> &'static str {
|
||||
"md5"
|
||||
}
|
||||
|
||||
fn examples() -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "md5 encode a string",
|
||||
example: "echo 'abcdefghijklmnopqrstuvwxyz' | hash md5",
|
||||
result: Some(Value::String {
|
||||
val: "c3fcd3d76192e4007dfb496cca67e13b".to_owned(),
|
||||
span: Span::unknown(),
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
description: "md5 encode a file",
|
||||
example: "open ./nu_0_24_1_windows.zip | hash md5",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::hash::generic_digest;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
crate::test_examples(HashMd5::default())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hash_string() {
|
||||
let binary = Value::String {
|
||||
val: "abcdefghijklmnopqrstuvwxyz".to_owned(),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let expected = Value::String {
|
||||
val: "c3fcd3d76192e4007dfb496cca67e13b".to_owned(),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let actual = generic_digest::action::<Md5>(&binary);
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hash_bytes() {
|
||||
let binary = Value::Binary {
|
||||
val: vec![0xC0, 0xFF, 0xEE],
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let expected = Value::String {
|
||||
val: "5f80e231382769b0102b1164cf722d83".to_owned(),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let actual = generic_digest::action::<Md5>(&binary);
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
}
|
8
crates/nu-command/src/hash/mod.rs
Normal file
8
crates/nu-command/src/hash/mod.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
mod command;
|
||||
mod generic_digest;
|
||||
mod md5;
|
||||
mod sha256;
|
||||
|
||||
pub use self::command::Hash;
|
||||
pub use self::md5::HashMd5;
|
||||
pub use self::sha256::HashSha256;
|
69
crates/nu-command/src/hash/sha256.rs
Normal file
69
crates/nu-command/src/hash/sha256.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
use super::generic_digest::{GenericDigest, HashDigest};
|
||||
use ::sha2::Sha256;
|
||||
use nu_protocol::{Example, Span, Value};
|
||||
|
||||
pub type HashSha256 = GenericDigest<Sha256>;
|
||||
|
||||
impl HashDigest for Sha256 {
|
||||
fn name() -> &'static str {
|
||||
"sha256"
|
||||
}
|
||||
|
||||
fn examples() -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "sha256 encode a string",
|
||||
example: "echo 'abcdefghijklmnopqrstuvwxyz' | hash sha256",
|
||||
result: Some(Value::String {
|
||||
val: "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73"
|
||||
.to_owned(),
|
||||
span: Span::unknown(),
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
description: "sha256 encode a file",
|
||||
example: "open ./nu_0_24_1_windows.zip | hash sha256",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::hash::generic_digest;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
crate::test_examples(HashSha256::default())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hash_string() {
|
||||
let binary = Value::String {
|
||||
val: "abcdefghijklmnopqrstuvwxyz".to_owned(),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let expected = Value::String {
|
||||
val: "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73".to_owned(),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let actual = generic_digest::action::<Sha256>(&binary);
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hash_bytes() {
|
||||
let binary = Value::Binary {
|
||||
val: vec![0xC0, 0xFF, 0xEE],
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let expected = Value::String {
|
||||
val: "c47a10dc272b1221f0380a2ae0f7d7fa830b3e378f2f5309bbf13f61ad211913".to_owned(),
|
||||
span: Span::unknown(),
|
||||
};
|
||||
let actual = generic_digest::action::<Sha256>(&binary);
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ mod experimental;
|
|||
mod filesystem;
|
||||
mod filters;
|
||||
mod formats;
|
||||
mod hash;
|
||||
mod math;
|
||||
mod network;
|
||||
mod platform;
|
||||
|
@ -29,6 +30,7 @@ pub use experimental::*;
|
|||
pub use filesystem::*;
|
||||
pub use filters::*;
|
||||
pub use formats::*;
|
||||
pub use hash::*;
|
||||
pub use math::*;
|
||||
pub use network::*;
|
||||
pub use platform::*;
|
||||
|
|
|
@ -49,6 +49,7 @@ pub enum Category {
|
|||
Strings,
|
||||
System,
|
||||
Viewers,
|
||||
Hash,
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
|
@ -72,6 +73,7 @@ impl std::fmt::Display for Category {
|
|||
Category::Strings => "strings",
|
||||
Category::System => "system",
|
||||
Category::Viewers => "viewers",
|
||||
Category::Hash => "hash",
|
||||
Category::Custom(name) => name,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue