use std::io::Read;
use anyhow::bail;
use quick_xml::events::Event;
use crate::{
excel::XmlReader,
helper::{extract_text_contents, string_to_int, string_to_unsignedint},
};
pub type XlsxFromMarker = XlsxMarker;
pub(crate) fn load_from_marker(reader: &mut XmlReader<impl Read>) -> anyhow::Result<XlsxToMarker> {
return XlsxMarker::load(reader, b"from");
}
pub type XlsxToMarker = XlsxMarker;
pub(crate) fn load_to_marker(reader: &mut XmlReader<impl Read>) -> anyhow::Result<XlsxToMarker> {
return XlsxMarker::load(reader, b"to");
}
#[derive(Debug, Clone, PartialEq)]
pub struct XlsxMarker {
pub column_id: Option<u64>,
pub column_offset: Option<i64>,
pub row_id: Option<u64>,
pub row_offset: Option<i64>,
}
impl XlsxMarker {
pub(crate) fn load(reader: &mut XmlReader<impl Read>, tag: &[u8]) -> anyhow::Result<Self> {
let mut buf = Vec::new();
let mut properties = Self {
column_id: None,
column_offset: None,
row_id: None,
row_offset: None,
};
loop {
buf.clear();
match reader.read_event_into(&mut buf) {
Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"col" => {
let str = extract_text_contents(reader, b"col")?;
properties.column_id = string_to_unsignedint(&str)
}
Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"colOff" => {
let str = extract_text_contents(reader, b"colOff")?;
properties.column_offset = string_to_int(&str)
}
Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"row" => {
let str = extract_text_contents(reader, b"row")?;
properties.row_id = string_to_unsignedint(&str)
}
Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"rowOff" => {
let str = extract_text_contents(reader, b"rowOff")?;
properties.row_offset = string_to_int(&str)
}
Ok(Event::End(ref e)) if e.local_name().as_ref() == tag => break,
Ok(Event::Eof) => {
bail!(
"unexpected end of file at Marker: `{}`.",
String::from_utf8(tag.to_vec())?
)
}
Err(e) => bail!(e.to_string()),
_ => (),
}
}
Ok(properties)
}
}