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(#[from] handlebars::RenderError),
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 orphaned_document(file: PathBuf) -> Self {
119 Self::new(
120 file,
121 None,
122 "document isn't included in any toctree".to_string(),
123 WarningType::OrphanedDocument,
124 )
125 }
126
127 #[allow(dead_code)]
128 pub fn broken_cross_reference(file: PathBuf, line: Option<usize>, reference: &str) -> Self {
129 Self::new(
130 file,
131 line,
132 format!("cross-reference target not found: '{}'", reference),
133 WarningType::BrokenCrossReference,
134 )
135 }
136}
137
138impl BuildErrorReport {
139 #[allow(dead_code)]
140 pub fn new(file: PathBuf, line: Option<usize>, message: String, error_type: ErrorType) -> Self {
141 Self {
142 file,
143 line,
144 message,
145 error_type,
146 }
147 }
148}