1use std::path::PathBuf;
2use thiserror::Error;
3
4#[derive(Error, Debug)]
5#[allow(dead_code)]
6pub enum BuildError {
7 #[error("IO error: {0}")]
8 Io(#[from] std::io::Error),
9
10 #[error("JSON serialization error: {0}")]
11 Json(#[from] serde_json::Error),
12
13 #[error("YAML serialization error: {0}")]
14 Yaml(#[from] serde_yaml::Error),
15
16 #[error("Template rendering error: {0}")]
17 Template(String),
18
19 #[error("File parsing error: {file}: {message}")]
20 Parse { file: String, message: String },
21
22 #[error("Cache error: {0}")]
23 Cache(String),
24
25 #[error("Configuration error: {0}")]
26 Config(String),
27
28 #[error("Thread pool error: {0}")]
29 ThreadPool(#[from] rayon::ThreadPoolBuildError),
30
31 #[error("File not found: {0}")]
32 FileNotFound(String),
33
34 #[error("Invalid document format: {0}")]
35 InvalidFormat(String),
36
37 #[error("Cross-reference error: {reference} not found")]
38 CrossReference { reference: String },
39
40 #[error("Template not found: {0}")]
41 TemplateNotFound(String),
42
43 #[error("Syntax highlighting error: {0}")]
44 SyntaxHighlight(String),
45
46 #[error("Validation error: {0}")]
47 ValidationError(String),
48}
49
50#[derive(Debug, Clone)]
51pub struct BuildWarning {
52 pub file: PathBuf,
53 pub line: Option<usize>,
54 pub message: String,
55 #[allow(dead_code)]
56 pub warning_type: WarningType,
57}
58
59#[derive(Debug, Clone)]
60pub struct BuildErrorReport {
61 pub file: PathBuf,
62 pub line: Option<usize>,
63 pub message: String,
64 #[allow(dead_code)]
65 pub error_type: ErrorType,
66}
67
68#[derive(Debug, Clone)]
69#[allow(dead_code)]
70pub enum WarningType {
71 MissingToctreeRef,
72 OrphanedDocument,
73 BrokenCrossReference,
74 MissingFile,
75 UnusedLabel,
76 DuplicateLabel,
77 EmptyToctree,
78 Other,
79}
80
81#[derive(Debug, Clone)]
82#[allow(dead_code)]
83pub enum ErrorType {
84 ParseError,
85 FileNotFound,
86 TemplateError,
87 SyntaxError,
88 Other,
89}
90
91impl BuildWarning {
92 pub fn new(
93 file: PathBuf,
94 line: Option<usize>,
95 message: String,
96 warning_type: WarningType,
97 ) -> Self {
98 Self {
99 file,
100 line,
101 message,
102 warning_type,
103 }
104 }
105
106 pub fn missing_toctree_ref(file: PathBuf, line: Option<usize>, reference: &str) -> Self {
107 Self::new(
108 file,
109 line,
110 format!(
111 "toctree contains reference to nonexisting document '{}'",
112 reference
113 ),
114 WarningType::MissingToctreeRef,
115 )
116 }
117
118 pub fn toctree_glob_no_match(file: PathBuf, line: Option<usize>, pattern: &str) -> Self {
119 Self::new(
120 file,
121 line,
122 format!(
123 "toctree glob pattern '{}' didn't match any documents",
124 pattern
125 ),
126 WarningType::EmptyToctree,
127 )
128 }
129
130 pub fn orphaned_document(file: PathBuf) -> Self {
131 Self::new(
132 file,
133 None,
134 "document isn't included in any toctree".to_string(),
135 WarningType::OrphanedDocument,
136 )
137 }
138
139 #[allow(dead_code)]
140 pub fn broken_cross_reference(file: PathBuf, line: Option<usize>, reference: &str) -> Self {
141 Self::new(
142 file,
143 line,
144 format!("cross-reference target not found: '{}'", reference),
145 WarningType::BrokenCrossReference,
146 )
147 }
148}
149
150impl BuildErrorReport {
151 pub fn new(file: PathBuf, line: Option<usize>, message: String, error_type: ErrorType) -> Self {
152 Self {
153 file,
154 line,
155 message,
156 error_type,
157 }
158 }
159}