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
//! Error types for asset operations.
use alloc::string::String;
use core::fmt;
/// Errors that can occur during asset operations.
#[derive(Debug)]
pub enum AssetError {
/// Asset file not found.
NotFound {
/// Path or URL that was not found.
path: String,
},
/// I/O error reading asset.
Io {
/// Description of the I/O error.
message: String,
},
/// Network error fetching remote asset.
Network {
/// URL that failed.
url: String,
/// HTTP status code if available.
status: Option<u16>,
/// Error message.
message: String,
},
/// Memory mapping failed.
Mmap {
/// Path that failed to mmap.
path: String,
/// Error message.
message: String,
},
/// Invalid asset path or URL.
InvalidPath {
/// The invalid path.
path: String,
/// Reason for invalidity.
reason: String,
},
/// HTTP protocol not allowed (must use HTTPS).
HttpNotAllowed {
/// The URL that used HTTP.
url: String,
},
}
impl fmt::Display for AssetError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NotFound { path } => write!(f, "Asset not found: {path}"),
Self::Io { message } => write!(f, "I/O error: {message}"),
Self::Network {
url,
status,
message,
} => {
if let Some(code) = status {
write!(f, "Network error for {url}: HTTP {code} - {message}")
} else {
write!(f, "Network error for {url}: {message}")
}
}
Self::Mmap { path, message } => {
write!(f, "Memory mapping failed for {path}: {message}")
}
Self::InvalidPath { path, reason } => {
write!(f, "Invalid asset path '{path}': {reason}")
}
Self::HttpNotAllowed { url } => {
write!(
f,
"HTTP not allowed (use HTTPS): {url}. Only loopback hosts permit HTTP."
)
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for AssetError {}
impl AssetError {
/// Create a not found error.
#[must_use]
pub fn not_found(path: impl Into<String>) -> Self {
Self::NotFound { path: path.into() }
}
/// Create an I/O error.
#[must_use]
pub fn io(message: impl Into<String>) -> Self {
Self::Io {
message: message.into(),
}
}
/// Create a network error.
#[must_use]
pub fn network(
url: impl Into<String>,
status: Option<u16>,
message: impl Into<String>,
) -> Self {
Self::Network {
url: url.into(),
status,
message: message.into(),
}
}
/// Create an mmap error.
#[must_use]
pub fn mmap(path: impl Into<String>, message: impl Into<String>) -> Self {
Self::Mmap {
path: path.into(),
message: message.into(),
}
}
/// Create an invalid path error.
#[must_use]
pub fn invalid_path(path: impl Into<String>, reason: impl Into<String>) -> Self {
Self::InvalidPath {
path: path.into(),
reason: reason.into(),
}
}
/// Create an HTTP not allowed error.
#[must_use]
pub fn http_not_allowed(url: impl Into<String>) -> Self {
Self::HttpNotAllowed { url: url.into() }
}
}