use std::collections::BTreeMap;
use std::fmt;
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct Error {
pub code: &'static str,
pub message: String,
pub partial: Option<Partial>,
pub stale_stages: Vec<String>,
}
impl Error {
pub(super) fn new(code: &'static str, message: &(impl ToString + ?Sized)) -> Self {
Self {
code,
message: message.to_string(),
partial: None,
stale_stages: Vec::new(),
}
}
pub(super) fn with_partial(mut self, completed: &[String], published: bool) -> Self {
if !completed.is_empty() {
self.partial = Some(Partial {
name: "bundle_partial",
completed: completed.to_vec(),
published,
});
}
self
}
pub(super) fn with_stale_stages(mut self, stages: Vec<String>) -> Self {
self.stale_stages = stages;
self
}
pub(super) fn with_cleanup(mut self, error: &Self) -> Self {
self.message.push_str("; ");
self.message.push_str(&error.to_string());
self
}
}
#[derive(Debug)]
pub struct Partial {
pub name: &'static str,
pub completed: Vec<String>,
pub published: bool,
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}: {}", self.code, self.message)?;
if let Some(partial) = &self.partial {
write!(
formatter,
"; {}: completed={:?}; published={}",
partial.name, partial.completed, partial.published
)?;
}
if !self.stale_stages.is_empty() {
write!(formatter, "; stale_stages={:?}", self.stale_stages)?;
}
Ok(())
}
}
impl std::error::Error for Error {}
#[derive(Debug, Serialize)]
pub struct Report {
pub directory: String,
pub files: usize,
pub already_installed: bool,
pub stale_stages: Vec<String>,
}
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub(super) struct Manifest {
pub format: u32,
pub files: BTreeMap<String, Entry>,
}
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
pub(super) struct Entry {
pub bytes: u64,
pub sha256: String,
pub mode: u32,
}