1use std::{error::Error, fmt};
2
3pub type Result<T> = std::result::Result<T, TuffError>;
4
5#[derive(Debug)]
6pub struct TuffError(String);
7
8impl TuffError {
9 pub fn new(message: impl Into<String>) -> Self {
10 Self(message.into())
11 }
12}
13
14impl fmt::Display for TuffError {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 write!(f, "{}", self.0)
17 }
18}
19
20impl Error for TuffError {}
21
22impl From<std::io::Error> for TuffError {
23 fn from(error: std::io::Error) -> Self {
24 Self(error.to_string())
25 }
26}
27
28impl From<serde_json::Error> for TuffError {
29 fn from(error: serde_json::Error) -> Self {
30 Self(error.to_string())
31 }
32}
33
34impl From<toml::de::Error> for TuffError {
35 fn from(error: toml::de::Error) -> Self {
36 Self(format!("invalid capability manifest TOML: {error}"))
37 }
38}
39
40impl From<toml::ser::Error> for TuffError {
41 fn from(error: toml::ser::Error) -> Self {
42 Self(format!("could not serialize TOML: {error}"))
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn tuff_error_displays_message() {
52 let err = TuffError::new("test error");
53 assert_eq!(format!("{}", err), "test error");
54 }
55
56 #[test]
57 fn tuff_error_from_io_error() {
58 let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
59 let err: TuffError = io_err.into();
60 assert!(format!("{}", err).contains("file not found"));
61 }
62
63 #[test]
64 fn tuff_error_from_serde_json_error() {
65 let json_err = serde_json::from_str::<serde_json::Value>("invalid").unwrap_err();
66 let err: TuffError = json_err.into();
67 assert!(!format!("{}", err).is_empty());
68 }
69}