1use std::{error, fmt, io, path, result};
2
3pub type TopiaryConfigResult<T> = result::Result<T, TopiaryConfigError>;
4
5#[derive(Debug)]
6#[allow(clippy::large_enum_variant)]
7pub enum TopiaryConfigError {
8 FileNotFound(path::PathBuf),
9 UnknownLanguage(String),
10 UnknownExtension(String),
11 NoExtension(path::PathBuf),
12 #[cfg(not(target_arch = "wasm32"))]
13 QueryFileNotFound(path::PathBuf),
14 Io(io::Error),
15 Missing,
16 TreeSitterFacade(topiary_tree_sitter_facade::LanguageError),
17 Nickel(Box<nickel_lang_core::error::Error>),
18 NickelDeserialization(nickel_lang_core::deserialize::RustDeserializationError),
19 #[cfg(not(target_arch = "wasm32"))]
20 Fetching(TopiaryConfigFetchingError),
21}
22
23#[derive(Debug)]
24#[cfg(not(target_arch = "wasm32"))]
28pub enum TopiaryConfigFetchingError {
29 Git(anyhow::Error),
30 Build(tree_sitter_loader::LoaderError),
31 Io(io::Error),
32 LibLoading(libloading::Error),
33 GrammarFileNotFound(path::PathBuf),
34}
35
36impl fmt::Display for TopiaryConfigError {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 match self {
39 TopiaryConfigError::FileNotFound(path) => write!(
40 f,
41 "We tried to find your configuration file at {}, but failed to do so. Make sure the file exists.",
42 path.display()
43 ),
44 TopiaryConfigError::UnknownLanguage(lang) => write!(
45 f,
46 "You were looking for language \"{lang}\", but we do not know that language."
47 ),
48 TopiaryConfigError::UnknownExtension(ext) => write!(
49 f,
50 "You tried to format a file with extension: \"{ext}\", but we do not know that extension. Make sure the extension is in your configuration file!"
51 ),
52 TopiaryConfigError::NoExtension(path) => write!(
53 f,
54 "You tried to format {} without specifying a language, but we cannot automatically detect the language because we can't find the filetype extension.",
55 path.display()
56 ),
57 #[cfg(not(target_arch = "wasm32"))]
58 TopiaryConfigError::QueryFileNotFound(path) => write!(
59 f,
60 "We could not find the query file: \"{}\" anywhere. If you use the TOPIARY_LANGUAGE_DIR environment variable, make sure it set set correctly.",
61 path.display()
62 ),
63 TopiaryConfigError::Io(error) => write!(f, "We encountered an io error: {error}"),
64 TopiaryConfigError::Missing => write!(
65 f,
66 "A configuration file is missing. If you passed a configuration file, make sure it exists."
67 ),
68 TopiaryConfigError::TreeSitterFacade(_) => {
69 write!(f, "We could not load the grammar for the given language")
70 }
71 TopiaryConfigError::Nickel(e) => write!(
72 f,
73 "Nickel error: {e:#?}\n\nDid you forget to add a \"priority\" annotation in your config file?"
74 ),
75 TopiaryConfigError::NickelDeserialization(e) => write!(f, "Nickel error: {e:#?}"),
76 #[cfg(not(target_arch = "wasm32"))]
77 TopiaryConfigError::Fetching(e) => write!(f, "Error Fetching Language: {e}"),
78 }
79 }
80}
81
82#[cfg(not(target_arch = "wasm32"))]
83impl fmt::Display for TopiaryConfigFetchingError {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 match self {
86 TopiaryConfigFetchingError::Git(e) => write!(f, "Git error: {e:?}"),
87 TopiaryConfigFetchingError::Build(e) => {
88 write!(f, "Compilation error: {e},")
89 }
90 TopiaryConfigFetchingError::Io(error) => {
91 write!(f, "We encountered an io error: {error}")
92 }
93 TopiaryConfigFetchingError::LibLoading(e) => write!(f, "Libloading error: {e:?}"),
94 TopiaryConfigFetchingError::GrammarFileNotFound(path) => write!(
95 f,
96 "Attempted to load grammar at `{}`, but no file found",
97 path.display()
98 ),
99 }
100 }
101}
102
103impl From<nickel_lang_core::deserialize::RustDeserializationError> for TopiaryConfigError {
104 fn from(e: nickel_lang_core::deserialize::RustDeserializationError) -> Self {
105 Self::NickelDeserialization(e)
106 }
107}
108
109impl From<nickel_lang_core::error::Error> for TopiaryConfigError {
110 fn from(e: nickel_lang_core::error::Error) -> Self {
111 Self::Nickel(e.into())
112 }
113}
114
115#[cfg(not(target_arch = "wasm32"))]
116impl From<TopiaryConfigFetchingError> for TopiaryConfigError {
117 fn from(e: TopiaryConfigFetchingError) -> Self {
118 Self::Fetching(e)
119 }
120}
121
122impl From<io::Error> for TopiaryConfigError {
123 fn from(e: io::Error) -> Self {
124 Self::Io(e)
125 }
126}
127
128#[cfg(not(target_arch = "wasm32"))]
129impl From<io::Error> for TopiaryConfigFetchingError {
130 fn from(e: io::Error) -> Self {
131 Self::Io(e)
132 }
133}
134
135impl From<topiary_tree_sitter_facade::LanguageError> for TopiaryConfigError {
136 fn from(e: topiary_tree_sitter_facade::LanguageError) -> Self {
137 Self::TreeSitterFacade(e)
138 }
139}
140
141#[cfg(not(target_arch = "wasm32"))]
142impl From<libloading::Error> for TopiaryConfigFetchingError {
143 fn from(e: libloading::Error) -> Self {
144 Self::LibLoading(e)
145 }
146}
147
148impl error::Error for TopiaryConfigError {
149 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
150 match self {
151 #[cfg(not(target_arch = "wasm32"))]
152 TopiaryConfigError::Io(e) => e.source(),
153 _ => None,
154 }
155 }
156}