1use std::fmt;
2use std::io;
3
4pub type Result<T> = std::result::Result<T, Error>;
6
7#[derive(Debug)]
9pub enum Error {
10 InvalidInput(String),
12 UnknownMember(String),
14 Io {
16 operation: &'static str,
18 source: io::Error,
20 },
21 UpdateInProgress {
23 lock: std::path::PathBuf,
25 },
26 DestinationConflict {
28 destination: std::path::PathBuf,
30 },
31 VerificationFailed(String),
33 CandidateExecution(String),
35}
36
37impl Error {
38 pub(crate) fn invalid(message: impl Into<String>) -> Self {
39 Self::InvalidInput(message.into())
40 }
41
42 pub(crate) fn io(operation: &'static str, source: io::Error) -> Self {
43 Self::Io { operation, source }
44 }
45}
46
47impl fmt::Display for Error {
48 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
49 match self {
50 Self::InvalidInput(message) => write!(formatter, "invalid update input: {message}"),
51 Self::UnknownMember(member) => write!(formatter, "unknown artifact member: {member}"),
52 Self::Io { operation, source } => write!(formatter, "{operation}: {source}"),
53 Self::UpdateInProgress { lock } => {
54 write!(
55 formatter,
56 "installation update already in progress: {}",
57 lock.display()
58 )
59 }
60 Self::DestinationConflict { destination } => write!(
61 formatter,
62 "destination failed ownership revalidation: {}",
63 destination.display()
64 ),
65 Self::VerificationFailed(message) => {
66 write!(formatter, "verification failed: {message}")
67 }
68 Self::CandidateExecution(message) => {
69 write!(formatter, "candidate execution failed: {message}")
70 }
71 }
72 }
73}
74
75impl std::error::Error for Error {
76 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
77 match self {
78 Self::Io { source, .. } => Some(source),
79 Self::InvalidInput(_)
80 | Self::UnknownMember(_)
81 | Self::UpdateInProgress { .. }
82 | Self::DestinationConflict { .. }
83 | Self::VerificationFailed(_)
84 | Self::CandidateExecution(_) => None,
85 }
86 }
87}