mirror of
https://git.um-react.app/um/lib_um_crypto_rust.git
synced 2026-03-08 04:29:54 +00:00
feat: add experimental cli
This commit is contained in:
9
um_cli/src/cmd/mod.rs
Normal file
9
um_cli/src/cmd/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use clap::Subcommand;
|
||||
|
||||
pub mod qmc1;
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Commands {
|
||||
#[command(name = "qmc1")]
|
||||
QMCv1(qmc1::ArgsQMCv1),
|
||||
}
|
||||
41
um_cli/src/cmd/qmc1.rs
Normal file
41
um_cli/src/cmd/qmc1.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use anyhow::Result;
|
||||
use clap::Args;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Decrypt a QMCv1 file
|
||||
#[derive(Args)]
|
||||
pub struct ArgsQMCv1 {
|
||||
/// Path to output file, e.g. /export/Music/song.flac
|
||||
#[clap(short, long)]
|
||||
output: PathBuf,
|
||||
|
||||
/// Path to input file, e.g. /export/Music/song.qmcflac
|
||||
#[arg(name = "input")]
|
||||
input: PathBuf,
|
||||
}
|
||||
|
||||
// 4MiB buffer is working well on my machine.
|
||||
const BUFFER_SIZE: usize = 4 * 1024 * 1024;
|
||||
|
||||
impl ArgsQMCv1 {
|
||||
pub fn run(&self) -> Result<i32> {
|
||||
let mut file_input = File::open(&self.input)?;
|
||||
let mut file_output = File::create(&self.output)?;
|
||||
|
||||
let mut offset = 0usize;
|
||||
let mut buffer = vec![0u8; BUFFER_SIZE].into_boxed_slice();
|
||||
while let Ok(n) = file_input.read(&mut buffer) {
|
||||
if n == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
umc_qmc::v1::decrypt(&mut buffer[..n], offset);
|
||||
file_output.write_all(&buffer[..n])?;
|
||||
offset += n;
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
44
um_cli/src/main.rs
Normal file
44
um_cli/src/main.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use crate::cmd::Commands;
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use std::process::exit;
|
||||
use std::time::Instant;
|
||||
|
||||
mod cmd;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "um_cli")]
|
||||
#[command(version = "0.1")]
|
||||
#[command(about = "um_cli (rust ver.)", long_about = None)]
|
||||
struct Cli {
|
||||
#[clap(subcommand)]
|
||||
command: Option<Commands>,
|
||||
|
||||
/// Time command
|
||||
#[clap(long, short, action=clap::ArgAction::SetTrue)]
|
||||
time: Option<bool>,
|
||||
}
|
||||
|
||||
fn run_command(cli: &Cli) -> Result<i32> {
|
||||
match &cli.command {
|
||||
Some(Commands::QMCv1(cmd)) => cmd.run(),
|
||||
None => {
|
||||
// https://github.com/clap-rs/clap/issues/3857#issuecomment-1161796261
|
||||
todo!("implement a sensible default command, similar to um/cli");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let cli = Cli::parse();
|
||||
let start = Instant::now();
|
||||
let code = run_command(&cli).unwrap_or_else(|err| {
|
||||
eprintln!("failed to run command: {}", err);
|
||||
-1
|
||||
});
|
||||
let duration = start.elapsed();
|
||||
if let Some(true) = cli.time {
|
||||
eprintln!("time: {:?}", duration);
|
||||
};
|
||||
exit(code);
|
||||
}
|
||||
Reference in New Issue
Block a user