loki_file_access/
error.rs1#[derive(Debug, thiserror::Error)]
21#[non_exhaustive]
22pub enum PickerError {
23 #[error("platform file-picker error: {message}")]
25 Platform {
26 message: String,
28 },
29
30 #[error("operation not supported on this platform: {operation}")]
32 Unsupported {
33 operation: String,
35 },
36
37 #[error("internal synchronisation error: {message}")]
39 Internal {
40 message: String,
42 },
43}
44
45#[derive(Debug, thiserror::Error)]
47#[non_exhaustive]
48pub enum AccessError {
49 #[error("file access permission has been revoked")]
51 PermissionRevoked,
52
53 #[error("I/O error: {source}")]
55 Io {
56 #[from]
58 source: std::io::Error,
59 },
60
61 #[error("invalid file descriptor returned by platform")]
63 InvalidDescriptor,
64
65 #[error("platform access error: {message}")]
67 Platform {
68 message: String,
70 },
71}
72
73#[derive(Debug, thiserror::Error)]
75#[non_exhaustive]
76pub enum TokenParseError {
77 #[error("invalid base64 encoding: {message}")]
79 InvalidBase64 {
80 message: String,
82 },
83
84 #[error("invalid JSON in token: {message}")]
86 InvalidJson {
87 message: String,
89 },
90
91 #[error("unknown token variant: {variant}")]
93 UnknownVariant {
94 variant: String,
96 },
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn picker_error_platform_displays_message() {
105 let err = PickerError::Platform {
106 message: "dialog failed".into(),
107 };
108 let msg = err.to_string();
109 assert!(!msg.is_empty(), "display string must not be empty");
110 assert!(msg.contains("dialog failed"));
111 }
112
113 #[test]
114 fn picker_error_unsupported_displays_message() {
115 let err = PickerError::Unsupported {
116 operation: "save".into(),
117 };
118 let msg = err.to_string();
119 assert!(!msg.is_empty());
120 assert!(msg.contains("save"));
121 }
122
123 #[test]
124 fn picker_error_internal_displays_message() {
125 let err = PickerError::Internal {
126 message: "mutex poisoned".into(),
127 };
128 let msg = err.to_string();
129 assert!(!msg.is_empty());
130 assert!(msg.contains("mutex poisoned"));
131 }
132
133 #[test]
134 fn access_error_permission_revoked_displays_message() {
135 let err = AccessError::PermissionRevoked;
136 assert!(!err.to_string().is_empty());
137 }
138
139 #[test]
140 fn access_error_io_displays_message() {
141 let err = AccessError::Io {
142 source: std::io::Error::new(std::io::ErrorKind::NotFound, "gone"),
143 };
144 assert!(!err.to_string().is_empty());
145 }
146
147 #[test]
148 fn access_error_invalid_descriptor_displays_message() {
149 let err = AccessError::InvalidDescriptor;
150 assert!(!err.to_string().is_empty());
151 }
152
153 #[test]
154 fn access_error_platform_displays_message() {
155 let err = AccessError::Platform {
156 message: "fd error".into(),
157 };
158 let msg = err.to_string();
159 assert!(!msg.is_empty());
160 assert!(msg.contains("fd error"));
161 }
162
163 #[test]
164 fn token_parse_error_base64_displays_message() {
165 let err = TokenParseError::InvalidBase64 {
166 message: "bad padding".into(),
167 };
168 let msg = err.to_string();
169 assert!(!msg.is_empty());
170 assert!(msg.contains("bad padding"));
171 }
172
173 #[test]
174 fn token_parse_error_json_displays_message() {
175 let err = TokenParseError::InvalidJson {
176 message: "unexpected EOF".into(),
177 };
178 let msg = err.to_string();
179 assert!(!msg.is_empty());
180 assert!(msg.contains("unexpected EOF"));
181 }
182
183 #[test]
184 fn token_parse_error_unknown_variant_displays_message() {
185 let err = TokenParseError::UnknownVariant {
186 variant: "FuturePlatform".into(),
187 };
188 let msg = err.to_string();
189 assert!(!msg.is_empty());
190 assert!(msg.contains("FuturePlatform"));
191 }
192}