1use eure_document::document::NodeId;
4use thiserror::Error;
5
6#[derive(Debug, Error)]
8pub enum EumdError {
9 #[error("Parse error: {0}")]
11 Parse(String),
12
13 #[error("Document error: {0}")]
15 Document(#[from] eure_document::parse::ParseError),
16
17 #[error("Reference errors:\n{}", format_reference_errors(.0))]
19 ReferenceErrors(Vec<ReferenceError>),
20}
21
22#[derive(Debug, Clone)]
24pub struct ReferenceError {
25 pub ref_type: ReferenceType,
27 pub key: String,
29 pub location: String,
31 pub node_id: Option<NodeId>,
33 pub offset: Option<u32>,
35 pub len: Option<u32>,
37}
38
39impl ReferenceError {
40 pub fn new(ref_type: ReferenceType, key: String, location: String) -> Self {
42 Self {
43 ref_type,
44 key,
45 location,
46 node_id: None,
47 offset: None,
48 len: None,
49 }
50 }
51
52 pub fn with_span(
54 ref_type: ReferenceType,
55 key: String,
56 location: String,
57 node_id: NodeId,
58 offset: u32,
59 len: u32,
60 ) -> Self {
61 Self {
62 ref_type,
63 key,
64 location,
65 node_id: Some(node_id),
66 offset: Some(offset),
67 len: Some(len),
68 }
69 }
70}
71
72#[derive(Debug, Clone, Copy, PartialEq, Eq)]
74pub enum ReferenceType {
75 Cite,
77 Footnote,
79 Section,
81}
82
83impl std::fmt::Display for ReferenceType {
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 match self {
86 ReferenceType::Cite => write!(f, "cite"),
87 ReferenceType::Footnote => write!(f, "footnote"),
88 ReferenceType::Section => write!(f, "ref"),
89 }
90 }
91}
92
93impl std::fmt::Display for ReferenceError {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 write!(
96 f,
97 "Undefined !{}[{}] {}",
98 self.ref_type, self.key, self.location
99 )
100 }
101}
102
103fn format_reference_errors(errors: &[ReferenceError]) -> String {
104 errors
105 .iter()
106 .map(|e| format!(" - {e}"))
107 .collect::<Vec<_>>()
108 .join("\n")
109}