use serde::Serialize;
pub mod daemon;
pub mod stats;
pub mod submit;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum ErrorKind {
Usage,
Validation,
Runtime,
Connectivity,
}
impl ErrorKind {
pub const fn exit_code(self) -> i32 {
match self {
ErrorKind::Usage => 2,
ErrorKind::Validation => 3,
ErrorKind::Runtime => 4,
ErrorKind::Connectivity => 5,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CliError {
kind: ErrorKind,
code: &'static str,
message: String,
}
impl CliError {
pub fn usage(code: &'static str, message: impl Into<String>) -> Self {
Self { kind: ErrorKind::Usage, code, message: message.into() }
}
pub fn validation(code: &'static str, message: impl Into<String>) -> Self {
Self { kind: ErrorKind::Validation, code, message: message.into() }
}
pub fn runtime(code: &'static str, message: impl Into<String>) -> Self {
Self { kind: ErrorKind::Runtime, code, message: message.into() }
}
pub fn connectivity(code: &'static str, message: impl Into<String>) -> Self {
Self { kind: ErrorKind::Connectivity, code, message: message.into() }
}
pub const fn kind(&self) -> ErrorKind {
self.kind
}
pub const fn code(&self) -> &'static str {
self.code
}
pub fn message(&self) -> &str {
&self.message
}
}
impl std::fmt::Display for CliError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", self.code, self.message)
}
}
impl std::error::Error for CliError {}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct ErrorPayload<'a> {
pub error_kind: ErrorKind,
pub error_code: &'a str,
pub message: &'a str,
}
#[derive(Debug, Clone, PartialEq)]
#[must_use]
pub enum CommandOutput {
Text(String),
Json(serde_json::Value),
}
pub fn now_unix_seconds() -> Result<u64, CliError> {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map_err(|err| CliError::runtime("runtime_clock_error", err.to_string()))
.map(|duration| duration.as_secs())
}
pub fn resolve_data_dir(override_dir: Option<&std::path::Path>) -> std::path::PathBuf {
override_dir.map(ToOwned::to_owned).unwrap_or_else(|| {
std::env::var("HOME")
.map(|h| std::path::PathBuf::from(h).join(".actionqueue/data"))
.unwrap_or_else(|_| std::path::PathBuf::from(".actionqueue/data"))
})
}