Skip to main content

xml_arrow/reader/
error.rs

1use std::{error::Error, io};
2
3/// Result with [`ReadError`].
4pub type Result<T> = std::result::Result<T, ReadError>;
5
6/// XML input limit.
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub enum Limit {
9    /// Serialized XML bytes retained for inference.
10    SampleBytes,
11    /// Document element depth.
12    Depth,
13    /// Record bytes, including inherited namespaces.
14    RecordBytes,
15    /// Input bytes per event, including skipped content.
16    EventBytes,
17}
18
19/// XML reader error.
20#[derive(Debug, thiserror::Error)]
21pub enum ReadError {
22    /// Invalid options or record path.
23    #[error("invalid configuration: {0}")]
24    Configuration(String),
25    /// XML, UTF-8, or input error.
26    #[error("XML input at byte {byte_offset}: {source}")]
27    Xml {
28        /// Input byte offset.
29        byte_offset: u64,
30        /// Underlying error; XML locations may be event-relative.
31        source: Box<dyn Error + Send + Sync>,
32    },
33    /// Input limit exceeded.
34    #[error("{kind:?} limit {limit} exceeded at byte {byte_offset}")]
35    LimitExceeded {
36        /// Exceeded limit.
37        kind: Limit,
38        /// Configured maximum.
39        limit: usize,
40        /// Input byte offset.
41        byte_offset: u64,
42    },
43    /// Record conversion failed.
44    #[error("record {record_index} at byte {byte_offset}: {source}")]
45    Conversion {
46        /// One-based index among selected records.
47        record_index: u64,
48        /// Record start byte offset.
49        byte_offset: u64,
50        /// Underlying conversion error.
51        source: crate::Error,
52    },
53}
54
55impl ReadError {
56    pub(super) fn configuration(error: crate::Error) -> Self {
57        Self::Configuration(match error {
58            crate::Error::Configuration(message) => message,
59            error => error.to_string(),
60        })
61    }
62
63    pub(super) fn xml(byte_offset: u64, source: impl Error + Send + Sync + 'static) -> Self {
64        Self::Xml {
65            byte_offset,
66            source: Box::new(source),
67        }
68    }
69
70    pub(super) fn invalid(byte_offset: u64, message: &str) -> Self {
71        Self::xml(
72            byte_offset,
73            io::Error::new(io::ErrorKind::InvalidData, message.to_owned()),
74        )
75    }
76
77    pub(super) fn limit(kind: Limit, limit: usize, byte_offset: u64) -> Self {
78        Self::LimitExceeded {
79            kind,
80            limit,
81            byte_offset,
82        }
83    }
84}