1use core::fmt;
2use std::io;
3
4use zip::result::ZipError;
5
6use crate::parse_error::ParseError;
7
8#[derive(Debug)]
9pub enum LssgErrorKind {
10 ParseError,
11 Render,
13 Request,
14 SiteTree,
16 Io,
17}
18
19#[derive(Debug)]
20pub struct LssgError {
21 message: String,
22 context: Option<String>,
23 #[allow(dead_code)]
24 kind: LssgErrorKind,
25}
26impl LssgError {
27 pub fn new<S: Into<String>>(message: S, kind: LssgErrorKind) -> LssgError {
28 LssgError {
29 message: message.into(),
30 kind,
31 context: None,
32 }
33 }
34
35 pub fn parse<S: Into<String>>(message: S) -> LssgError {
36 Self::new(message, LssgErrorKind::ParseError)
37 }
38
39 pub fn sitetree<S: Into<String>>(message: S) -> LssgError {
40 Self::new(message, LssgErrorKind::SiteTree)
41 }
42
43 pub fn render<S: Into<String>>(message: S) -> LssgError {
44 Self::new(message, LssgErrorKind::Render)
45 }
46
47 pub fn io<S: Into<String>>(message: S) -> LssgError {
48 Self::new(message, LssgErrorKind::Io)
49 }
50
51 pub fn with_context(mut self, context: impl Into<String>) -> Self {
52 self.context = Some(context.into());
53 self
54 }
55}
56impl From<ParseError> for LssgError {
57 fn from(error: ParseError) -> Self {
58 Self::new(error.to_string(), LssgErrorKind::ParseError)
59 }
60}
61impl From<chrono::ParseError> for LssgError {
62 fn from(value: chrono::ParseError) -> Self {
63 Self::new(
64 format!("Failed to parse date: {value}"),
65 LssgErrorKind::ParseError,
66 )
67 }
68}
69impl From<io::Error> for LssgError {
70 fn from(error: io::Error) -> Self {
71 Self::new(error.to_string(), LssgErrorKind::Io)
72 }
73}
74impl From<reqwest::Error> for LssgError {
75 fn from(error: reqwest::Error) -> Self {
76 Self::new(error.to_string(), LssgErrorKind::Request)
77 }
78}
79impl From<ZipError> for LssgError {
80 fn from(error: ZipError) -> Self {
81 Self::new(error.to_string(), LssgErrorKind::Io)
82 }
83}
84impl std::error::Error for LssgError {}
85
86impl fmt::Display for LssgError {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 let context = if let Some(context) = &self.context {
89 format!("with context '{context}'")
90 } else {
91 "".into()
92 };
93 write!(
94 f,
95 "Error when generating static files: '{}' {context}",
96 self.message
97 )
98 }
99}