pub mod meta;
pub mod restore;
pub use meta::{BackupFile, BackupMeta};
pub use restore::{DEFAULT_CONCURRENCY, RestoreOptions, fetch_meta, list_backup_ids, restore};
use std::io;
use std::path::PathBuf;
use std::string::FromUtf8Error;
use object_store::path::Path as StorePath;
#[cfg(feature = "easy")]
pub fn public_bucket(
endpoint: &str,
) -> Result<std::sync::Arc<dyn object_store::ObjectStore>, Error> {
use object_store::aws::AmazonS3Builder;
use std::sync::Arc;
let store = AmazonS3Builder::new()
.with_endpoint(endpoint)
.with_bucket_name("_")
.with_skip_signature(true)
.with_allow_http(true)
.with_virtual_hosted_style_request(true)
.build()
.map_err(|e| Error::ObjectStoreBuild {
endpoint: endpoint.to_string(),
source: e,
})?;
Ok(Arc::new(store))
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[cfg(feature = "easy")]
#[error("failed to build object store")]
ObjectStoreBuild {
endpoint: String,
#[source]
source: object_store::Error,
},
#[error("failed to list objects under {prefix:?}")]
List {
prefix: StorePath,
#[source]
source: object_store::Error,
},
#[error("failed to fetch {key:?}")]
Fetch {
key: StorePath,
#[source]
source: object_store::Error,
},
#[error("meta file for backup {backup_id} is not valid UTF-8")]
MetaEncoding {
backup_id: u64,
#[source]
source: FromUtf8Error,
},
#[error("failed to parse meta file for backup {backup_id}")]
MetaParse {
backup_id: u64,
#[source]
source: meta::ParseError,
},
#[error("no backups found")]
NoBackups,
#[error("backup contains {count} excluded file(s) (unsupported)")]
ExcludedFiles { count: usize },
#[error("backup path has unrecognized prefix: {0:?}")]
UnrecognizedPathPrefix(String),
#[error("shared_checksum filename missing underscore: {0:?}")]
SharedChecksumNoUnderscore(String),
#[error("shared_checksum filename missing extension: {0:?}")]
SharedChecksumNoExtension(String),
#[error("private/ path has too few components: {0:?}")]
PrivatePathTooShort(String),
#[error("size mismatch on {path}: expected {expected} bytes, got {actual}")]
SizeMismatch {
path: String,
expected: u64,
actual: u64,
},
#[error("crc32c mismatch on {path}: expected {expected:#010x}, got {actual:#010x}")]
ChecksumMismatch {
path: String,
expected: u32,
actual: u32,
},
#[error("{}: {source}", path.display())]
Io {
path: PathBuf,
#[source]
source: io::Error,
},
}