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
163
164
//! Failures a user can cause, with enough context to fix them.
use std::path::PathBuf;
use kallo_io::IoError;
/// Everything the model can fail at.
#[derive(Debug)]
pub enum Error {
/// The requested stock id is not compiled in.
UnknownStock {
/// `"film"` or `"paper"`.
kind: &'static str,
/// The id the user typed.
id: String,
},
/// A numeric flag received a value outside its domain.
InvalidNumber {
/// The flag, e.g. `"--dev"`.
flag: &'static str,
/// The value the user typed.
value: f64,
/// What was expected, e.g. `"a positive number of minutes"`.
expected: &'static str,
},
/// The output directory could not be created.
CreateDir {
/// The directory that failed.
path: PathBuf,
/// The underlying OS error.
source: std::io::Error,
},
/// A camera raw file could not be decoded.
Raw {
/// The file that failed.
path: PathBuf,
/// What the decoder said.
message: String,
},
/// The input could not be decoded.
Read {
/// The file that failed.
path: PathBuf,
/// The underlying decoder error.
source: IoError,
},
/// A `.kalofilm` file could not be read or verified.
Film {
/// The file that failed.
path: PathBuf,
/// What the loader said.
message: String,
},
/// A stock file could not be read, parsed or checked.
Stock {
/// The file that failed.
path: PathBuf,
/// What the checker said.
message: String,
},
/// The dictionary could not be read.
Dictionary {
/// The file that failed.
path: PathBuf,
/// What the loader said.
message: String,
},
/// The build has no GPU backend, or the one it has cannot run this render.
Gpu {
/// What to tell the user.
message: String,
},
/// A camera sensitivity file could not be read.
Camera {
/// The file that failed.
path: PathBuf,
/// What went wrong.
message: String,
},
/// A baked table could not be read or written.
Lut {
/// The file that failed.
path: PathBuf,
/// What the table layer said.
message: String,
},
/// A contact proof could not be made, or its record written.
Contact {
/// What to tell the user.
message: String,
},
/// The output could not be encoded.
Write {
/// The file that failed.
path: PathBuf,
/// The underlying encoder error.
source: IoError,
},
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::UnknownStock { kind, id } => {
write!(f, "unknown {kind} stock '{id}' (try `kalo stocks`)")
}
Self::InvalidNumber {
flag,
value,
expected,
} => {
write!(f, "{flag} must be {expected}, got {value}")
}
Self::CreateDir { path, source } => {
write!(f, "could not create {}: {source}", path.display())
}
Self::Raw { path, message } => {
write!(f, "could not decode raw file {}: {message}", path.display())
}
Self::Read { path, source } => {
write!(f, "could not read {}: {source}", path.display())
}
Self::Film { path, message } => {
write!(f, "could not load film {}: {message}", path.display())
}
Self::Dictionary { path, message } => {
write!(f, "could not read dictionary {}: {message}", path.display())
}
Self::Stock { path, message } => {
write!(f, "stock {}: {message}", path.display())
}
Self::Gpu { message } => write!(f, "{message}"),
Self::Camera { path, message } => {
write!(f, "camera sensitivity {}: {message}", path.display())
}
Self::Lut { path, message } => {
write!(f, "lookup table {}: {message}", path.display())
}
Self::Contact { message } => write!(f, "{message}"),
Self::Write { path, source } => {
write!(f, "could not write {}: {source}", path.display())
}
}
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::CreateDir { source, .. } => Some(source),
Self::Read { source, .. } | Self::Write { source, .. } => Some(source),
Self::UnknownStock { .. }
| Self::InvalidNumber { .. }
| Self::Film { .. }
| Self::Raw { .. }
| Self::Dictionary { .. }
| Self::Camera { .. }
| Self::Gpu { .. }
| Self::Lut { .. }
| Self::Stock { .. }
| Self::Contact { .. } => None,
}
}
}