1use std::fmt;
18use std::io;
19use std::path::PathBuf;
20
21pub use crate::archive::ZipError;
22pub use crate::build::BuildError;
23
24pub use crate::manifest::ManifestError;
25pub use crate::native::NativeError;
26pub use crate::res::{
27 ChunkError, LiteralError, LocaleError, QualifierError, ResourceError, ResourceNameError, ResourceRefError,
28 StringPoolError, TableError,
29};
30pub use crate::sign::{CoverageError, JarError, KeyError, SignError, VerifyError};
31pub use crate::types::{
32 ApiLevelError, ArchivePathError, ClassNameError, LibraryNameError, PackageNameError, PermissionNameError,
33 UnknownAbi, VersionCodeError,
34};
35pub use crate::xml::XmlError;
36
37pub type Result<T, E = Error> = std::result::Result<T, E>;
39
40#[derive(Debug, thiserror::Error)]
42#[non_exhaustive]
43pub enum Error {
44 #[error("failed to {operation} `{}`", path.display())]
46 File {
47 operation: FileOperation,
48 path: PathBuf,
49 #[source]
50 source: io::Error,
51 },
52 #[error(transparent)]
54 Io(#[from] io::Error),
55 #[error(transparent)]
56 Value(#[from] ValueError),
57 #[error(transparent)]
58 Zip(#[from] ZipError),
59 #[error(transparent)]
60 Table(#[from] TableError),
61 #[error(transparent)]
62 Xml(#[from] XmlError),
63 #[error(transparent)]
64 Manifest(#[from] ManifestError),
65 #[error(transparent)]
66 Resource(#[from] ResourceError),
67 #[error(transparent)]
68 Native(#[from] NativeError),
69 #[error(transparent)]
70 Key(#[from] KeyError),
71 #[error(transparent)]
72 Sign(#[from] SignError),
73 #[error(transparent)]
74 Verify(#[from] VerifyError),
75 #[error(transparent)]
76 Build(#[from] BuildError),
77}
78
79#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
81pub enum FileOperation {
82 Open,
83 Read,
84 Create,
85 Write,
86 Inspect,
87 Persist,
88}
89
90impl fmt::Display for FileOperation {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 f.write_str(match self {
93 Self::Open => "open",
94 Self::Read => "read",
95 Self::Create => "create",
96 Self::Write => "write",
97 Self::Inspect => "inspect",
98 Self::Persist => "persist",
99 })
100 }
101}
102
103impl Error {
104 pub(crate) fn file(operation: FileOperation, path: impl Into<PathBuf>) -> impl FnOnce(io::Error) -> Self {
106 let path = path.into();
107 move |source| Self::File { operation, path, source }
108 }
109}
110
111#[derive(Clone, Debug, PartialEq, thiserror::Error)]
113#[non_exhaustive]
114pub enum ValueError {
115 #[error(transparent)]
116 PackageName(#[from] PackageNameError),
117 #[error(transparent)]
118 ClassName(#[from] ClassNameError),
119 #[error(transparent)]
120 PermissionName(#[from] PermissionNameError),
121 #[error(transparent)]
122 LibraryName(#[from] LibraryNameError),
123 #[error(transparent)]
124 ArchivePath(#[from] ArchivePathError),
125 #[error("invalid API level: {0}")]
126 ApiLevel(#[from] ApiLevelError),
127 #[error("invalid version code: {0}")]
128 VersionCode(#[from] VersionCodeError),
129 #[error(transparent)]
130 Abi(#[from] UnknownAbi),
131 #[error(transparent)]
132 ResourceName(#[from] ResourceNameError),
133 #[error(transparent)]
134 ResourceRef(#[from] ResourceRefError),
135 #[error(transparent)]
136 Locale(#[from] LocaleError),
137 #[error(transparent)]
138 Qualifier(#[from] QualifierError),
139 #[error(transparent)]
140 Literal(#[from] LiteralError),
141}
142
143macro_rules! value_errors_into_error {
145 ($($ty:ty),+ $(,)?) => {
146 $(impl From<$ty> for Error {
147 fn from(error: $ty) -> Self {
148 Self::Value(error.into())
149 }
150 })+
151 };
152}
153
154value_errors_into_error!(
155 PackageNameError,
156 ClassNameError,
157 PermissionNameError,
158 LibraryNameError,
159 ArchivePathError,
160 ApiLevelError,
161 VersionCodeError,
162 UnknownAbi,
163 ResourceNameError,
164 ResourceRefError,
165 LocaleError,
166 QualifierError,
167 LiteralError,
168);