1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//! One error type for the whole crate.
//!
//! Every variant carries the thing a person needs to act: the path, the
//! encoding that had no decoder, the feature that was not compiled in. A
//! message that says only "decode failed" costs more time than it saves.
use std::path::PathBuf;
use crate::identify::Encoding;
/// What went wrong.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
/// The file, or the call, was about something not implemented here.
///
/// Carries what was asked for and, where there is one, the way to get it.
#[error("{what}")]
Unsupported {
/// What cannot be done, and what to do instead.
what: String,
},
/// The bytes are a container this crate cannot read.
#[error("{path}: not a container vtome reads ({found})")]
UnknownContainer {
/// The file.
path: PathBuf,
/// What identification made of it.
found: String,
},
/// Nothing in this build can decode that encoding on this machine.
///
/// Names the feature or the platform backend that would have handled it,
/// because "no decoder" on its own leaves a caller guessing between a
/// missing cargo feature and a missing operating system.
#[error("no decoder for {encoding}: {remedy}")]
NoDecoder {
/// The encoding that went unhandled.
encoding: Encoding,
/// The feature to enable, or the platform that would have done it.
remedy: String,
},
/// The container is malformed, or ends where it should not.
#[error("{path}: {reason}")]
Demux {
/// The file.
path: PathBuf,
/// What did not add up.
reason: String,
},
/// A decoder rejected a packet.
#[error("decoding {encoding}: {reason}")]
Decode {
/// What was being decoded.
encoding: Encoding,
/// What the decoder said.
reason: String,
},
/// Nothing in this build can encode that encoding on this machine — or
/// not in the way asked, such as in hardware where there is none.
#[error("no encoder for {encoding}: {remedy}")]
NoEncoder {
/// The encoding that went unwritten.
encoding: Encoding,
/// The feature to enable, the platform that would have done it, or
/// the setting that ruled every encoder out.
remedy: String,
},
/// An encoder failed.
#[error("encoding: {reason}")]
Encode {
/// What the encoder said.
reason: String,
},
/// A job was cancelled before it finished. Not a failure: what was asked
/// to stop, stopped.
#[error("cancelled")]
Cancelled,
/// A frame's planes do not describe a picture of that size.
#[error("{reason}")]
BadFrame {
/// Which dimension, stride, or plane count disagreed.
reason: String,
},
/// No monitor answers that selector.
#[error("no monitor matches {selector} ({available} attached)")]
NoSuchMonitor {
/// The selector as it was written.
selector: String,
/// How many monitors were actually there.
available: usize,
},
/// The placement cannot be drawn: a quad that folds over itself, a
/// rectangle with no area, an opacity outside 0..=1.
#[error("{reason}")]
Placement {
/// What is wrong with it.
reason: String,
},
/// The GPU could not be set up, or a surface was lost.
#[error("render: {reason}")]
Render {
/// What the graphics layer said.
reason: String,
},
/// [`std::io::Error`] alone does not say which file it was about, and by
/// the time it reaches a user that is the only part they need.
#[error("{path}: {source}")]
Io {
/// The file or directory the call was about.
path: PathBuf,
/// The underlying error.
#[source]
source: std::io::Error,
},
}
impl Error {
/// Attaches a path to an [`std::io::Error`].
pub(crate) fn io(path: impl Into<PathBuf>, source: std::io::Error) -> Self {
Error::Io {
path: path.into(),
source,
}
}
/// Something this build, or this platform, cannot do.
pub(crate) fn unsupported(what: impl Into<String>) -> Self {
Error::Unsupported { what: what.into() }
}
/// A container that does not parse.
#[cfg_attr(not(feature = "demux"), allow(dead_code))]
pub(crate) fn demux(path: impl Into<PathBuf>, reason: impl Into<String>) -> Self {
Error::Demux {
path: path.into(),
reason: reason.into(),
}
}
/// A placement that cannot be drawn.
pub(crate) fn placement(reason: impl Into<String>) -> Self {
Error::Placement {
reason: reason.into(),
}
}
}
/// [`Result`](std::result::Result) with this crate's error type.
pub type Result<T, E = Error> = std::result::Result<T, E>;