Files
pile/crates/pile/src/command/encrypt.rs
2026-03-23 21:09:22 -07:00

76 lines
1.9 KiB
Rust

use anyhow::{Context, Result};
use clap::Args;
use pile_io::AsyncReader;
use pile_io::chacha::{ChaChaReaderv1, ChaChaWriterv1};
use pile_toolbox::cancelabletask::{CancelFlag, CancelableTaskError};
use pile_value::source::string_to_key;
use std::io::{Cursor, Write};
use std::path::PathBuf;
use crate::{CliCmd, GlobalContext};
#[derive(Debug, Args)]
pub struct EncryptCommand {
/// File to encrypt
path: PathBuf,
/// Encryption password
password: String,
}
#[derive(Debug, Args)]
pub struct DecryptCommand {
/// File to decrypt
path: PathBuf,
/// Encryption password
password: String,
}
impl CliCmd for EncryptCommand {
async fn run(
self,
_ctx: GlobalContext,
_flag: CancelFlag,
) -> Result<i32, CancelableTaskError<anyhow::Error>> {
let key = string_to_key(&self.password);
let plaintext = tokio::fs::read(&self.path)
.await
.with_context(|| format!("while reading '{}'", self.path.display()))?;
let mut writer = ChaChaWriterv1::new(Cursor::new(Vec::new()), key)
.context("while initializing encryptor")?;
writer.write_all(&plaintext).context("while encrypting")?;
let buf = writer.finish().context("while finalizing encryptor")?;
std::io::stdout()
.write_all(buf.get_ref())
.context("while writing to stdout")?;
Ok(0)
}
}
impl CliCmd for DecryptCommand {
async fn run(
self,
_ctx: GlobalContext,
_flag: CancelFlag,
) -> Result<i32, CancelableTaskError<anyhow::Error>> {
let key = string_to_key(&self.password);
let ciphertext = tokio::fs::read(&self.path)
.await
.with_context(|| format!("while reading '{}'", self.path.display()))?;
let mut reader = ChaChaReaderv1::new(Cursor::new(ciphertext), key)
.context("while initializing decryptor")?;
let plaintext = reader.read_to_end().await.context("while decrypting")?;
std::io::stdout()
.write_all(&plaintext)
.context("while writing to stdout")?;
Ok(0)
}
}