oxrdfxml/
error.rs

1use oxilangtag::LanguageTagParseError;
2use oxiri::IriParseError;
3use quick_xml::encoding::EncodingError;
4use quick_xml::events::attributes::AttrError;
5use std::io;
6use std::sync::Arc;
7
8/// Error returned during RDF/XML parsing.
9#[derive(Debug, thiserror::Error)]
10pub enum RdfXmlParseError {
11    /// I/O error during parsing (file not found...).
12    #[error(transparent)]
13    Io(#[from] io::Error),
14    /// An error in the file syntax.
15    #[error(transparent)]
16    Syntax(#[from] RdfXmlSyntaxError),
17}
18
19impl From<RdfXmlParseError> for io::Error {
20    #[inline]
21    fn from(error: RdfXmlParseError) -> Self {
22        match error {
23            RdfXmlParseError::Io(error) => error,
24            RdfXmlParseError::Syntax(error) => error.into(),
25        }
26    }
27}
28
29#[doc(hidden)]
30impl From<quick_xml::Error> for RdfXmlParseError {
31    #[inline]
32    fn from(error: quick_xml::Error) -> Self {
33        match error {
34            quick_xml::Error::Io(error) => {
35                Self::Io(Arc::try_unwrap(error).unwrap_or_else(|e| io::Error::new(e.kind(), e)))
36            }
37            _ => Self::Syntax(RdfXmlSyntaxError(SyntaxErrorKind::Xml(error))),
38        }
39    }
40}
41
42#[doc(hidden)]
43impl From<EncodingError> for RdfXmlParseError {
44    fn from(error: EncodingError) -> Self {
45        quick_xml::Error::from(error).into()
46    }
47}
48
49#[doc(hidden)]
50impl From<AttrError> for RdfXmlParseError {
51    fn from(error: AttrError) -> Self {
52        quick_xml::Error::from(error).into()
53    }
54}
55
56/// An error in the syntax of the parsed file.
57#[derive(Debug, thiserror::Error)]
58#[error(transparent)]
59pub struct RdfXmlSyntaxError(#[from] SyntaxErrorKind);
60
61#[derive(Debug, thiserror::Error)]
62enum SyntaxErrorKind {
63    #[error(transparent)]
64    Xml(#[from] quick_xml::Error),
65    #[error("error while parsing IRI '{iri}': {error}")]
66    InvalidIri {
67        iri: String,
68        #[source]
69        error: IriParseError,
70    },
71    #[error("error while parsing language tag '{tag}': {error}")]
72    InvalidLanguageTag {
73        tag: String,
74        #[source]
75        error: LanguageTagParseError,
76    },
77    #[error("{0}")]
78    Msg(String),
79}
80
81impl RdfXmlSyntaxError {
82    /// Builds an error from a printable error message.
83    pub(crate) fn msg(msg: impl Into<String>) -> Self {
84        Self(SyntaxErrorKind::Msg(msg.into()))
85    }
86
87    pub(crate) fn invalid_iri(iri: String, error: IriParseError) -> Self {
88        Self(SyntaxErrorKind::InvalidIri { iri, error })
89    }
90
91    pub(crate) fn invalid_language_tag(tag: String, error: LanguageTagParseError) -> Self {
92        Self(SyntaxErrorKind::InvalidLanguageTag { tag, error })
93    }
94}
95
96impl From<RdfXmlSyntaxError> for io::Error {
97    #[inline]
98    fn from(error: RdfXmlSyntaxError) -> Self {
99        match error.0 {
100            SyntaxErrorKind::Xml(error) => match error {
101                quick_xml::Error::Io(error) => {
102                    Arc::try_unwrap(error).unwrap_or_else(|e| Self::new(e.kind(), e))
103                }
104                _ => Self::new(io::ErrorKind::InvalidData, error),
105            },
106            SyntaxErrorKind::Msg(msg) => Self::new(io::ErrorKind::InvalidData, msg),
107            _ => Self::new(io::ErrorKind::InvalidData, error),
108        }
109    }
110}