#![allow(clippy::multiple_crate_versions)]
mod app;
mod cli;
mod input;
mod output;
mod params;
mod passphrase;
mod utils;
use std::{
io,
process::{self, Termination},
};
use scryptenc::Error as ScryptencError;
#[derive(Debug)]
enum ExitCode {
Success,
Failure,
InvalidFormat,
UnknownVersion,
LackOfMemory,
LackOfCpuTime,
InvalidPassphrase,
InvalidParams,
LackOfResources,
Other(sysexits::ExitCode),
}
impl From<sysexits::ExitCode> for ExitCode {
fn from(code: sysexits::ExitCode) -> Self {
Self::Other(code)
}
}
impl Termination for ExitCode {
fn report(self) -> process::ExitCode {
match self {
Self::Success => process::ExitCode::SUCCESS,
Self::Failure => process::ExitCode::FAILURE,
Self::InvalidFormat => 7.into(),
Self::UnknownVersion => 8.into(),
Self::LackOfMemory => 9.into(),
Self::LackOfCpuTime => 10.into(),
Self::InvalidPassphrase => 11.into(),
Self::InvalidParams => 14.into(),
Self::LackOfResources => 15.into(),
Self::Other(code) => code.into(),
}
}
}
fn main() -> ExitCode {
match app::run() {
Ok(()) => ExitCode::Success,
Err(err) => {
eprintln!("Error: {err:?}");
if let Some(e) = err.downcast_ref::<io::Error>() {
return sysexits::ExitCode::from(e.kind()).into();
}
if let Some(e) = err.downcast_ref::<ScryptencError>() {
return match e {
ScryptencError::InvalidLength
| ScryptencError::InvalidMagicNumber
| ScryptencError::InvalidChecksum
| ScryptencError::InvalidMac(_) => ExitCode::InvalidFormat,
ScryptencError::UnknownVersion(_) => ExitCode::UnknownVersion,
ScryptencError::InvalidParams(_) => ExitCode::InvalidParams,
ScryptencError::InvalidHeaderMac(_) => ExitCode::InvalidPassphrase,
};
}
if let Some(e) = err.downcast_ref::<params::Error>() {
return match e {
params::Error::Memory => ExitCode::LackOfMemory,
params::Error::CpuTime => ExitCode::LackOfCpuTime,
params::Error::Resources => ExitCode::LackOfResources,
};
}
ExitCode::Failure
}
}
}