1use std::error::Error;
2
3use reqwest::{self, header};
4use tokio::sync::mpsc::error::SendError;
5use crate::encoder::tile_buffer::TileBufferMsg;
6use custom_error::custom_error;
7
8custom_error! {
9 pub ZoomError
10 Networking{source: reqwest::Error} = "network error: {source}",
11 Dezoomer{source: DezoomerError} = "Dezoomer error: {source}",
12 NoLevels = "A zoomable image was found, but it did not contain any zoom level",
13 NoTile = "Could not get any tile for the image. See https://dezoomify-rs.ophir.dev/no-tile-error",
14 PartialDownload{successful_tiles: u64, total_tiles: u64, destination: String} =
15 "Only {successful_tiles} tiles out of {total_tiles} could be downloaded. \
16 The resulting image was still created in '{destination}'.",
17 Image{source: image::ImageError} = "invalid image error: {source}",
18 PostProcessing{source: Box<dyn Error>} = "unable to process the downloaded tile: {source}",
19 Io{source: std::io::Error} = "Input/Output error: {source}",
20 Yaml{source: serde_yaml::Error} = "Invalid YAML configuration file: {source}",
21 TileCopyError{x:u32, y:u32, twidth:u32, theight:u32, width:u32, height:u32} =
22 "Unable to copy a {twidth}x{theight} tile \
23 at position {x},{y} \
24 on a canvas of size {width}x{height}",
25 MalformedTileStr{tile_str: String} = "Malformed tile string: '{tile_str}' \
26 expected 'x y url'",
27 NoSuchDezoomer{name: String} = "No such dezoomer: {name}",
28 InvalidHeaderName{source: header::InvalidHeaderName} = "Invalid header name: {source}",
29 InvalidHeaderValue{source: header::InvalidHeaderValue} = "Invalid header value: {source}",
30 AsyncError{source: tokio::task::JoinError} = "Unable get the result from a thread: {source}",
31 BufferToImage{source: BufferToImageError} = "{source}",
32 WriteError{source: SendError<TileBufferMsg>} = "Unable to write tile {source:?}",
33 PngError{source: png::EncodingError} = "PNG encoding error: {source}",
34}
35
36custom_error! {
37 pub BufferToImageError
38 Image{source: image::ImageError} = "invalid image error: {source}",
39 PostProcessing{e: Box<dyn Error + Send>} = "unable to process the downloaded tile: {e}",
40}
41
42custom_error! {pub DezoomerError
43 NeedsData{uri: String} = "Need to download data from {uri}",
44 WrongDezoomer{name:&'static str} = "The '{name}' dezoomer cannot handle this URI",
45 DownloadError{msg: String} = "Unable to download required data: {msg}",
46 Other{source: Box<dyn Error>} = "Unable to create the dezoomer: {source}"
47}
48
49impl DezoomerError {
50 pub fn wrap<E: Error + 'static>(err: E) -> DezoomerError {
51 DezoomerError::Other { source: err.into() }
52 }
53}
54
55pub fn image_error_to_io_error(err: image::ImageError) -> std::io::Error {
56 match err {
57 image::ImageError::IoError(e) => e,
58 e => make_io_err(e)
59 }
60}
61
62pub fn make_io_err<E>(e: E) -> std::io::Error
63 where E: Into<Box<dyn std::error::Error + Send + Sync>> {
64 std::io::Error::new(std::io::ErrorKind::Other, e)
65}