mod binaryxml;
mod stringpool;
mod xml;
use thiserror::Error;
use crate::binaryxml::BinaryXmlDocument;
pub use crate::xml::{Cdata, Element, Node, XmlDocument};
#[derive(Error, Debug)]
pub enum ParseError {
#[error("parse error: {0}")]
DekuError(deku::DekuError),
#[error("StringPool missing index: {0}")]
StringNotFound(u32),
#[error("Namespace missing: {0}")]
NamespaceNotFound(String),
#[error("ResourceMap missing index: {0}")]
ResourceIdNotFound(u32),
#[error("Unknown resource string: {0}")]
UnknownResourceString(u32),
#[error(transparent)]
Utf8StringParseError(std::string::FromUtf8Error),
#[error(transparent)]
Utf16StringParseError(std::string::FromUtf16Error),
}
pub fn parse(input: &[u8]) -> Result<XmlDocument, ParseError> {
let binaryxml = BinaryXmlDocument::try_from(input).map_err(ParseError::DekuError)?;
XmlDocument::new(binaryxml)
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
#[test]
fn test_parse() {
let mut examples = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
examples.push("examples");
for entry in std::fs::read_dir(examples).unwrap() {
let entry = entry.unwrap();
let mut f = File::open(entry.path()).unwrap();
let mut buf = Vec::new();
f.read_to_end(&mut buf).unwrap();
parse(&buf).expect(&format!("{} failed to parse", entry.path().display()));
}
}
}