tensorlogic_oxirs_bridge/
error.rs1use thiserror::Error;
4
5#[derive(Debug, Clone)]
7pub struct ParseLocation {
8 pub line: usize,
9 pub column: usize,
10 pub context: Option<String>,
11}
12
13impl ParseLocation {
14 pub fn new(line: usize, column: usize) -> Self {
15 Self {
16 line,
17 column,
18 context: None,
19 }
20 }
21
22 pub fn with_context(mut self, context: String) -> Self {
23 self.context = Some(context);
24 self
25 }
26}
27
28impl std::fmt::Display for ParseLocation {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 write!(f, "line {}, column {}", self.line, self.column)?;
31 if let Some(ctx) = &self.context {
32 write!(f, "\n {}", ctx)?;
33 }
34 Ok(())
35 }
36}
37
38#[derive(Error, Debug)]
39pub enum BridgeError {
40 #[error("Invalid RDF schema: {0}")]
41 InvalidSchema(String),
42
43 #[error("Parse error at {location}: {message}")]
44 ParseError {
45 location: ParseLocation,
46 message: String,
47 },
48
49 #[error("SHACL shape not supported: {0}")]
50 UnsupportedShape(String),
51
52 #[error("Property '{property}' not found in schema")]
53 PropertyNotFound { property: String },
54
55 #[error("Class '{class}' not found in schema")]
56 ClassNotFound { class: String },
57
58 #[error("Provenance tracking error: {0}")]
59 ProvenanceError(String),
60
61 #[error("Invalid IRI '{iri}': {reason}")]
62 InvalidIri { iri: String, reason: String },
63
64 #[error("Missing required field '{field}' in {context}")]
65 MissingField { field: String, context: String },
66
67 #[error("Validation error: {0}")]
68 ValidationError(String),
69
70 #[error("Index error: {0}")]
71 IndexError(String),
72
73 #[error("Cache error: {0}")]
74 CacheError(String),
75}
76
77impl BridgeError {
78 pub fn parse_error(line: usize, column: usize, message: impl Into<String>) -> Self {
80 Self::ParseError {
81 location: ParseLocation::new(line, column),
82 message: message.into(),
83 }
84 }
85
86 pub fn parse_error_with_context(
88 line: usize,
89 column: usize,
90 message: impl Into<String>,
91 context: impl Into<String>,
92 ) -> Self {
93 Self::ParseError {
94 location: ParseLocation::new(line, column).with_context(context.into()),
95 message: message.into(),
96 }
97 }
98
99 pub fn suggestion(&self) -> Option<String> {
101 match self {
102 Self::PropertyNotFound { property } => {
103 Some(format!("Did you mean to define a property with IRI '{}'? Add it to your RDF schema with 'a rdf:Property'.", property))
104 }
105 Self::ClassNotFound { class } => {
106 Some(format!("Did you mean to define a class with IRI '{}'? Add it to your RDF schema with 'a rdfs:Class'.", class))
107 }
108 Self::InvalidIri { iri, reason } => {
109 Some(format!("Ensure '{}' is a valid IRI. Reason: {}", iri, reason))
110 }
111 Self::MissingField { field, context } => {
112 Some(format!("Add the required field '{}' to {}", field, context))
113 }
114 _ => None,
115 }
116 }
117}