From d13ddb1498cc784a0da22c1569d404ed0912b40f Mon Sep 17 00:00:00 2001 From: Aadi Desai <21363892+supleed2@users.noreply.github.com> Date: Sun, 7 May 2023 18:45:47 +0100 Subject: [PATCH] Add file input and optional file output --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 67 +++++++++++++++++++++++++++++++++++------------------ 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc1ab85..6b48362 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -193,7 +193,7 @@ checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "namehash" -version = "0.1.0" +version = "0.1.1" dependencies = [ "clap", "hex", diff --git a/Cargo.toml b/Cargo.toml index 9e1c725..ce43686 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "namehash" -version = "0.1.0" +version = "0.1.1" edition = "2021" description = "CLI program for hashing domain names according to EIP-137" homepage = "https://github.com/supleed2/namehash-rs" diff --git a/src/main.rs b/src/main.rs index 98fcbb8..187b7ce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -// use std::path::PathBuf; +use std::io::prelude::*; use clap::{Parser, Subcommand}; @@ -15,30 +15,51 @@ enum Commands { /// Domain to get namehash of domain: String, }, - // /// Get the namehashes of many domains at once, THIS COMMAND IS INCOMPLETE - // File { - // /// Path to input file, domains to hash with 1 per line - // input: PathBuf, - // /// File to save hashes to, stdout if not given - // #[arg(short, long, value_name = "FILE")] - // output: Option, - // }, + /// Get the namehashes of many domains at once + File { + /// Path to input file, domains to hash with 1 per line + input: std::path::PathBuf, + /// File to save hashes to, stdout if not given + #[arg(short, long, value_name = "FILE")] + output: Option, + }, } -fn main() { +fn main() -> std::io::Result<()> { match Cli::parse().command { - Commands::Domain { domain } => println!("{domain}: 0x{}", hex::encode(namehash(&domain))), - // Commands::File { input, output } => match output { - // None => println!( - // "Hashing domains in {}, output to stdout, THIS COMMAND IS INCOMPLETE", - // input.display() - // ), - // Some(output) => println!( - // "Hashing domains in {}, output to {}, THIS COMMAND IS INCOMPLETE", - // input.display(), - // output.display() - // ), - // }, + Commands::Domain { domain } => { + println!("{domain}: 0x{}", hex::encode(namehash(&domain))); + Ok(()) + } + Commands::File { input, output } => match output { + None => { + let input = std::fs::File::open(input)?; + for line in std::io::BufReader::new(input).lines() { + match line { + Ok(domain) => { + println!("{domain}: 0x{}", hex::encode(namehash(&domain))) + } + Err(error) => eprintln!("Error: {error}"), + } + } + Ok(()) + } + Some(output) => { + let input = std::fs::File::open(input)?; + let mut outstr = String::new(); + for line in std::io::BufReader::new(input).lines() { + match line { + Ok(domain) => outstr + .push_str(&format!("{domain}: 0x{}\n", hex::encode(namehash(&domain)))), + Err(error) => eprintln!("Error: {error}"), + } + } + if let Some(folder) = std::path::Path::new(&output).parent() { + std::fs::create_dir_all(folder).unwrap(); + } + write!(std::fs::File::create(output)?, "{}", outstr) + } + }, } } @@ -56,7 +77,7 @@ fn namehash(name: &str) -> Vec { return vec![0u8; 32]; } let mut hash = vec![0u8; 32]; - for label in name.rsplit(".") { + for label in name.rsplit('.') { hash.append(&mut keccak256(label.as_bytes()).to_vec()); hash = keccak256(hash.as_slice()).to_vec(); }