1use std::io;
2
3use chrono::ParseError;
4use thiserror::Error;
5
6pub struct CliError {
7 pub error: Option<anyhow::Error>,
8 pub exit_code: i32,
9}
10
11impl CliError {
12 pub fn new(error: anyhow::Error, code: i32) -> Self {
13 Self {
14 error: Some(error),
15 exit_code: code,
16 }
17 }
18
19 pub const fn code(code: i32) -> Self {
21 Self {
22 error: None,
23 exit_code: code,
24 }
25 }
26}
27
28impl From<anyhow::Error> for CliError {
29 fn from(err: anyhow::Error) -> Self {
31 Self::new(err, 101)
32 }
33}
34
35impl From<clap::Error> for CliError {
36 fn from(err: clap::Error) -> Self {
38 let code = if err.use_stderr() { 1 } else { 0 };
39 Self::new(err.into(), code)
40 }
41}
42
43impl From<confy::ConfyError> for CliError {
44 fn from(err: confy::ConfyError) -> Self {
46 Self::new(err.into(), 101)
47 }
48}
49impl From<DiaryError> for CliError {
50 fn from(err: DiaryError) -> Self {
52 Self::new(err.into(), 202)
53 }
54}
55
56impl From<ParseError> for CliError {
57 fn from(err: ParseError) -> Self {
58 Self::new(err.into(), 101)
59 }
60}
61impl From<io::Error> for CliError {
62 fn from(err: io::Error) -> Self {
64 Self::new(err.into(), 1)
65 }
66}
67
68#[derive(Error, Debug)]
69pub enum DiaryError {
70 #[error("Diary folder already exists somewhere.")]
71 ExistsElsewhere,
72
73 #[error("Diary folder already exists at the path provided.")]
74 ExistsHere,
75
76 #[error("Diary has not been initialised. Use the `init` sub-command.")]
77 UnInitialised { source: Option<std::io::Error> },
78
79 #[error(transparent)]
80 IOError(#[from] std::io::Error),
81
82 #[error("The desired entry has not been found. You can use the `new` command to create today's entry.")]
83 NoEntry { source: Option<std::io::Error> },
84
85 #[error("No content provided, aborting.")]
86 NoContent,
87
88 #[error("Unsupported file type.")]
89 BadFileType,
90
91 #[error(transparent)]
92 GitError(#[from] git2::Error),
93}