modio/util/download/
error.rs1use std::fmt;
2
3use crate::types::id::{FileId, GameId, ModId};
4
5type Source = Box<dyn std::error::Error + Send + Sync>;
6
7pub struct Error {
11 kind: ErrorKind,
12 source: Option<Source>,
13}
14
15impl Error {
16 #[inline]
17 pub(crate) fn new(kind: ErrorKind) -> Self {
18 Self { kind, source: None }
19 }
20
21 #[inline]
22 pub(crate) fn with<E: Into<Source>>(mut self, source: E) -> Self {
23 self.source = Some(source.into());
24 self
25 }
26
27 pub const fn kind(&self) -> &ErrorKind {
28 &self.kind
29 }
30}
31
32impl Error {
33 #[inline]
34 pub(crate) fn request<E: Into<Source>>(source: E) -> Self {
35 Self::new(ErrorKind::Request).with(source)
36 }
37
38 #[inline]
39 pub(crate) fn body<E: Into<Source>>(source: E) -> Self {
40 Self::new(ErrorKind::Body).with(source)
41 }
42}
43
44impl fmt::Debug for Error {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 let mut s = f.debug_struct("Error");
47
48 s.field("kind", &self.kind);
49 if let Some(ref source) = self.source {
50 s.field("source", source);
51 }
52 s.finish()
53 }
54}
55
56impl fmt::Display for Error {
57 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
58 match &self.kind {
59 ErrorKind::Request => fmt.write_str("request failed"),
60 ErrorKind::Body => fmt.write_str("failed to load response body"),
61 ErrorKind::Io => fmt.write_str("IO error"),
62 ErrorKind::ModNotFound { game_id, mod_id } => write!(
63 fmt,
64 "Mod {{id: {mod_id}, game_id: {game_id}}} not found.",
65 ),
66 ErrorKind::FileNotFound {
67 game_id,
68 mod_id,
69 file_id,
70 } => write!(
71 fmt,
72 "Mod {{id: {mod_id}, game_id: {game_id}}}: File {{ id: {file_id} }} not found.",
73 ),
74 ErrorKind::MultipleFilesFound {
75 game_id,
76 mod_id,
77 version,
78 } => write!(
79 fmt,
80 "Mod {{id: {mod_id}, game_id: {game_id}}}: Multiple files found for version '{version}'.",
81 ),
82 ErrorKind::NoPrimaryFile { game_id, mod_id } => write!(
83 fmt,
84 "Mod {{id: {mod_id}, game_id: {game_id}}} Mod has no primary file.",
85 ),
86 ErrorKind::VersionNotFound {
87 game_id,
88 mod_id,
89 version,
90 } => write!(
91 fmt,
92 "Mod {{id: {mod_id}, game_id: {game_id}}}: No file with version '{version}' found.",
93 ),
94 }
95 }
96}
97
98impl std::error::Error for Error {
99 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
100 self.source.as_ref().map(|e| &**e as _)
101 }
102}
103
104#[derive(Debug)]
105pub enum ErrorKind {
106 Request,
107 Body,
108 Io,
109 ModNotFound {
111 game_id: GameId,
112 mod_id: ModId,
113 },
114 NoPrimaryFile {
116 game_id: GameId,
117 mod_id: ModId,
118 },
119 FileNotFound {
121 game_id: GameId,
122 mod_id: ModId,
123 file_id: FileId,
124 },
125 MultipleFilesFound {
130 game_id: GameId,
131 mod_id: ModId,
132 version: String,
133 },
134 VersionNotFound {
136 game_id: GameId,
137 mod_id: ModId,
138 version: String,
139 },
140}