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