use crate::{ObjectId, index};
#[derive(Clone, Copy, Debug)]
pub struct Limits {
pub index: index::Limits,
pub trees: crate::TreeCompareLimits,
pub packs: crate::PackLimits,
pub read: crate::ReadLimits,
pub max_object_bytes: usize,
pub max_file_bytes: usize,
pub max_worktree_bytes: usize,
pub max_directory_entries: usize,
pub max_path_bytes: usize,
pub max_depth: usize,
}
impl Default for Limits {
fn default() -> Self {
Self {
index: index::Limits::default(),
trees: crate::TreeCompareLimits::default(),
packs: crate::PackLimits::default(),
read: crate::ReadLimits::default(),
max_object_bytes: 256 * 1024 * 1024,
max_file_bytes: 16 * 1024 * 1024,
max_worktree_bytes: 256 * 1024 * 1024,
max_directory_entries: 1_000_000,
max_path_bytes: 64 * 1024 * 1024,
max_depth: 64,
}
}
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub enum Stage {
#[default]
Preparation,
Worktree,
Publication,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Action {
Remove,
RemoveDirectory,
CreateDirectory,
Install,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Applied {
pub path: Vec<u8>,
pub action: Action,
}
#[derive(Debug, Default)]
pub struct Report {
pub stage: Stage,
pub applied: Vec<Applied>,
pub index_published: bool,
}
#[derive(Debug, thiserror::Error)]
#[error("checkout failed during {stage:?}", stage = .report.stage)]
pub struct Failure {
#[source]
pub cause: Box<Error>,
pub report: Report,
pub cleanup: Vec<Error>,
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
ObjectFormat(#[from] crate::ObjectFormatError),
#[error("checkout refused at {path:?}: {reason}")]
Refused {
path: Vec<u8>,
reason: &'static str,
},
#[error("checkout cancelled")]
Cancelled,
#[error("checkout limit exceeded: {0}")]
Limit(&'static str),
#[error(transparent)]
Verification(#[from] Box<crate::status::Error>),
#[error(transparent)]
Index(#[from] index::StorageError),
#[error(transparent)]
IndexFormat(#[from] index::Error),
#[error(transparent)]
Tree(#[from] crate::TreeCompareError),
#[error(transparent)]
Object(#[from] crate::ObjectReadError),
#[error("missing or non-blob checkout object {0}")]
InvalidBlob(ObjectId),
#[error("checkout I/O at {path:?}")]
Io {
path: Vec<u8>,
#[source]
source: std::io::Error,
},
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
impl From<crate::status::Error> for Error {
fn from(source: crate::status::Error) -> Self {
Self::Verification(Box::new(source))
}
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
pub(super) fn check(cancel: &std::sync::atomic::AtomicBool) -> Result<(), Error> {
if cancel.load(std::sync::atomic::Ordering::Relaxed) {
Err(Error::Cancelled)
} else {
Ok(())
}
}
pub(super) fn refused(path: &[u8], reason: &'static str) -> Error {
Error::Refused {
path: path.to_vec(),
reason,
}
}