oxrdfio/
error.rs

1use std::io;
2use std::ops::Range;
3
4/// Error returned during RDF format parsing.
5#[derive(Debug, thiserror::Error)]
6pub enum RdfParseError {
7    /// I/O error during parsing (file not found...).
8    #[error(transparent)]
9    Io(#[from] io::Error),
10    /// An error in the file syntax.
11    #[error(transparent)]
12    Syntax(#[from] RdfSyntaxError),
13}
14
15impl From<oxjsonld::JsonLdParseError> for RdfParseError {
16    #[inline]
17    fn from(error: oxjsonld::JsonLdParseError) -> Self {
18        match error {
19            oxjsonld::JsonLdParseError::Syntax(e) => Self::Syntax(e.into()),
20            oxjsonld::JsonLdParseError::Io(e) => Self::Io(e),
21        }
22    }
23}
24
25impl From<oxttl::TurtleParseError> for RdfParseError {
26    #[inline]
27    fn from(error: oxttl::TurtleParseError) -> Self {
28        match error {
29            oxttl::TurtleParseError::Syntax(e) => Self::Syntax(e.into()),
30            oxttl::TurtleParseError::Io(e) => Self::Io(e),
31        }
32    }
33}
34
35impl From<oxrdfxml::RdfXmlParseError> for RdfParseError {
36    #[inline]
37    fn from(error: oxrdfxml::RdfXmlParseError) -> Self {
38        match error {
39            oxrdfxml::RdfXmlParseError::Syntax(e) => Self::Syntax(e.into()),
40            oxrdfxml::RdfXmlParseError::Io(e) => Self::Io(e),
41        }
42    }
43}
44
45impl From<RdfParseError> for io::Error {
46    #[inline]
47    fn from(error: RdfParseError) -> Self {
48        match error {
49            RdfParseError::Io(error) => error,
50            RdfParseError::Syntax(error) => error.into(),
51        }
52    }
53}
54
55/// An error in the syntax of the parsed file.
56#[derive(Debug, thiserror::Error)]
57#[error(transparent)]
58pub struct RdfSyntaxError(#[from] SyntaxErrorKind);
59
60/// An error in the syntax of the parsed file.
61#[derive(Debug, thiserror::Error)]
62enum SyntaxErrorKind {
63    #[error(transparent)]
64    JsonLd(#[from] oxjsonld::JsonLdSyntaxError),
65    #[error(transparent)]
66    Turtle(#[from] oxttl::TurtleSyntaxError),
67    #[error(transparent)]
68    RdfXml(#[from] oxrdfxml::RdfXmlSyntaxError),
69    #[error("{0}")]
70    Msg(&'static str),
71}
72
73impl RdfSyntaxError {
74    /// The location of the error inside of the file.
75    #[inline]
76    pub fn location(&self) -> Option<Range<TextPosition>> {
77        match &self.0 {
78            SyntaxErrorKind::JsonLd(e) => {
79                let location = e.location()?;
80                Some(
81                    TextPosition {
82                        line: location.start.line,
83                        column: location.start.column,
84                        offset: location.start.offset,
85                    }..TextPosition {
86                        line: location.end.line,
87                        column: location.end.column,
88                        offset: location.end.offset,
89                    },
90                )
91            }
92            SyntaxErrorKind::Turtle(e) => {
93                let location = e.location();
94                Some(
95                    TextPosition {
96                        line: location.start.line,
97                        column: location.start.column,
98                        offset: location.start.offset,
99                    }..TextPosition {
100                        line: location.end.line,
101                        column: location.end.column,
102                        offset: location.end.offset,
103                    },
104                )
105            }
106            SyntaxErrorKind::RdfXml(_) | SyntaxErrorKind::Msg(_) => None,
107        }
108    }
109
110    pub(crate) fn msg(msg: &'static str) -> Self {
111        Self(SyntaxErrorKind::Msg(msg))
112    }
113}
114
115impl From<oxjsonld::JsonLdSyntaxError> for RdfSyntaxError {
116    #[inline]
117    fn from(error: oxjsonld::JsonLdSyntaxError) -> Self {
118        Self(SyntaxErrorKind::JsonLd(error))
119    }
120}
121
122impl From<oxttl::TurtleSyntaxError> for RdfSyntaxError {
123    #[inline]
124    fn from(error: oxttl::TurtleSyntaxError) -> Self {
125        Self(SyntaxErrorKind::Turtle(error))
126    }
127}
128
129impl From<oxrdfxml::RdfXmlSyntaxError> for RdfSyntaxError {
130    #[inline]
131    fn from(error: oxrdfxml::RdfXmlSyntaxError) -> Self {
132        Self(SyntaxErrorKind::RdfXml(error))
133    }
134}
135
136impl From<RdfSyntaxError> for io::Error {
137    #[inline]
138    fn from(error: RdfSyntaxError) -> Self {
139        match error.0 {
140            SyntaxErrorKind::JsonLd(error) => error.into(),
141            SyntaxErrorKind::Turtle(error) => error.into(),
142            SyntaxErrorKind::RdfXml(error) => error.into(),
143            SyntaxErrorKind::Msg(msg) => Self::new(io::ErrorKind::InvalidData, msg),
144        }
145    }
146}
147
148/// A position in a text i.e. a `line` number starting from 0, a `column` number starting from 0 (in number of code points) and a global file `offset` starting from 0 (in number of bytes).
149#[derive(Eq, PartialEq, Debug, Clone, Copy)]
150pub struct TextPosition {
151    pub line: u64,
152    pub column: u64,
153    pub offset: u64,
154}