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

use std::error::Error;
use std::fmt::{Display, Formatter, Result};

/// An error that can occur while using the `google-fonts` crate.
///
/// This enum represents various errors that can be encountered while
/// downloading, deserializing, caching, or otherwise handling fonts
/// from Google Fonts. Each variant corresponds to a specific type
/// of error that can occur during the process.
///
/// # Variants
///
/// - `Network`: Indicates an error that occurred while making a network request.
/// - `Deserialize`: Indicates an error that occurred while deserializing JSON data.
/// - `CacheDir`: Indicates an error that occurred while interacting with the cache directory.
/// - `CacheFile`: Indicates an error that occurred while interacting with a cache file.
#[derive(Debug)]
pub enum FontError {
    /// An error that occurred while making a network request.
    ///
    /// This variant wraps a `reqwest::Error`, which provides more details
    /// about the specific network-related error that occurred.
    ///
    /// # Example
    ///
    /// ```rust
    /// use google_fonts::FontError;
    /// if let FontError::Network(e) = error {
    ///     println!("Network error: {}", e);
    /// }
    /// ```
    Network(reqwest::Error),

    /// An error that occurred while deserializing JSON data.
    ///
    /// This variant wraps a `serde_json::Error`, which provides more details
    /// about the specific deserialization error that occurred.
    ///
    /// # Example
    ///
    /// ```rust
    /// use google_fonts::FontError;
    /// if let FontError::Deserialize(e) = error {
    ///     println!("Deserialization error: {}", e);
    /// }
    /// ```
    Deserialize(serde_json::Error),

    /// An error that occurred while interacting with the cache directory.
    ///
    /// This variant wraps a `StringError`, which provides more details
    /// about the specific error related to the cache directory.
    ///
    /// # Example
    ///
    /// ```rust
    /// use google_fonts::FontError;
    /// if let FontError::CacheDir(e) = error {
    ///     println!("Cache directory error: {}", e);
    /// }
    /// ```
    CacheDir(StringError),

    /// An error that occurred while interacting with a cache file.
    ///
    /// This variant wraps a `std::io::Error`, which provides more details
    /// about the specific I/O error that occurred.
    ///
    /// # Example
    ///
    /// ```rust
    /// use google_fonts::FontError;
    /// if let FontError::CacheFile(e) = error {
    ///     println!("Cache file error: {}", e);
    /// }
    /// ```
    CacheFile(std::io::Error),
}

impl Display for FontError {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        match self {
            FontError::Network(e) => write!(f, "font network error: {}", e),
            FontError::Deserialize(e) => write!(f, "deserialization error: {}", e),
            FontError::CacheDir(e) => write!(f, "font cache directory error: {}", e),
            FontError::CacheFile(e) => write!(f, "font cache file error: {}", e),
        }
    }
}

impl Error for FontError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match self {
            FontError::Network(e) => Some(e),
            FontError::Deserialize(e) => Some(e),
            FontError::CacheDir(e) => Some(e),
            FontError::CacheFile(e) => Some(e),
        }
    }
}

#[derive(Debug)]
pub struct StringError {
    msg: String,
}
impl StringError {
    pub fn new(msg: &str) -> Self {
        Self {
            msg: msg.to_string(),
        }
    }
}
impl Display for StringError {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}", self.msg)
    }
}
impl Error for StringError {}