use thiserror::Error;
pub mod commands;
pub mod crypto;
pub mod git;
pub mod rules;
pub mod util;
#[derive(Debug, Error)]
pub enum Error {
#[error("i/o failure: {0}")]
Io(#[from] std::io::Error),
#[error("could not draw randomness from the operating system: {0}")]
Entropy(String),
#[error("format error: {0}")]
Format(String),
#[error(
"this file was encrypted with key {}, but the repository holds key {}",
hex(wanted),
hex(have)
)]
KeyMismatch {
wanted: [u8; crypto::format::KEY_ID_LEN],
have: [u8; crypto::format::KEY_ID_LEN],
},
#[error("{0}")]
Crypto(String),
#[error("{0}")]
Config(String),
#[error("no repository key; run `git-xcrypt init` or `git-xcrypt unlock <key-file>`")]
NoKey,
#[error("{0}")]
Usage(String),
}
impl Error {
#[must_use]
pub fn exit_code(&self) -> u8 {
match self {
Self::Usage(_) | Self::Io(_) | Self::Entropy(_) => util::exit::USAGE,
Self::Config(_) => util::exit::CONFIG,
Self::NoKey => util::exit::NO_KEY,
Self::Format(_) | Self::KeyMismatch { .. } | Self::Crypto(_) => util::exit::FORMAT,
}
}
}
pub type Result<T> = std::result::Result<T, Error>;
fn hex(bytes: &[u8]) -> String {
bytes.iter().map(|byte| format!("{byte:02x}")).collect()
}
#[must_use]
pub fn format_key_id(key_id: &[u8; crypto::format::KEY_ID_LEN]) -> String {
hex(key_id)
}