use std::fmt;
use std::io;
use std::path::PathBuf;
pub use crate::archive::ZipError;
pub use crate::build::BuildError;
pub use crate::manifest::ManifestError;
pub use crate::native::NativeError;
pub use crate::res::{
ChunkError, LiteralError, LocaleError, QualifierError, ResourceError, ResourceNameError, ResourceRefError,
StringPoolError, TableError,
};
pub use crate::sign::{CoverageError, JarError, KeyError, SignError, VerifyError};
pub use crate::types::{
ApiLevelError, ArchivePathError, ClassNameError, LibraryNameError, PackageNameError, PermissionNameError,
UnknownAbi, VersionCodeError,
};
pub use crate::xml::XmlError;
pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("failed to {operation} `{}`", path.display())]
File {
operation: FileOperation,
path: PathBuf,
#[source]
source: io::Error,
},
#[error(transparent)]
Io(#[from] io::Error),
#[error(transparent)]
Value(#[from] ValueError),
#[error(transparent)]
Zip(#[from] ZipError),
#[error(transparent)]
Table(#[from] TableError),
#[error(transparent)]
Xml(#[from] XmlError),
#[error(transparent)]
Manifest(#[from] ManifestError),
#[error(transparent)]
Resource(#[from] ResourceError),
#[error(transparent)]
Native(#[from] NativeError),
#[error(transparent)]
Key(#[from] KeyError),
#[error(transparent)]
Sign(#[from] SignError),
#[error(transparent)]
Verify(#[from] VerifyError),
#[error(transparent)]
Build(#[from] BuildError),
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum FileOperation {
Open,
Read,
Create,
Write,
Inspect,
Persist,
}
impl fmt::Display for FileOperation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Open => "open",
Self::Read => "read",
Self::Create => "create",
Self::Write => "write",
Self::Inspect => "inspect",
Self::Persist => "persist",
})
}
}
impl Error {
pub(crate) fn file(operation: FileOperation, path: impl Into<PathBuf>) -> impl FnOnce(io::Error) -> Self {
let path = path.into();
move |source| Self::File { operation, path, source }
}
}
#[derive(Clone, Debug, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum ValueError {
#[error(transparent)]
PackageName(#[from] PackageNameError),
#[error(transparent)]
ClassName(#[from] ClassNameError),
#[error(transparent)]
PermissionName(#[from] PermissionNameError),
#[error(transparent)]
LibraryName(#[from] LibraryNameError),
#[error(transparent)]
ArchivePath(#[from] ArchivePathError),
#[error("invalid API level: {0}")]
ApiLevel(#[from] ApiLevelError),
#[error("invalid version code: {0}")]
VersionCode(#[from] VersionCodeError),
#[error(transparent)]
Abi(#[from] UnknownAbi),
#[error(transparent)]
ResourceName(#[from] ResourceNameError),
#[error(transparent)]
ResourceRef(#[from] ResourceRefError),
#[error(transparent)]
Locale(#[from] LocaleError),
#[error(transparent)]
Qualifier(#[from] QualifierError),
#[error(transparent)]
Literal(#[from] LiteralError),
}
macro_rules! value_errors_into_error {
($($ty:ty),+ $(,)?) => {
$(impl From<$ty> for Error {
fn from(error: $ty) -> Self {
Self::Value(error.into())
}
})+
};
}
value_errors_into_error!(
PackageNameError,
ClassNameError,
PermissionNameError,
LibraryNameError,
ArchivePathError,
ApiLevelError,
VersionCodeError,
UnknownAbi,
ResourceNameError,
ResourceRefError,
LocaleError,
QualifierError,
LiteralError,
);