use super::*;
#[derive(Default)]
pub(super) struct LibraryImages<'a> {
pub(super) images: HashMap<&'a str, Image<'a>>,
}
pub(super) struct Image<'a> {
pub(super) id: &'a str,
pub(super) source: ImageSource<'a>,
}
pub(super) enum ImageSource<'a> {
Data(Vec<u8>),
InitFrom(&'a str),
Skip,
}
pub(super) fn parse_library_images<'a>(
cx: &mut Context<'a>,
node: xml::Node<'a, '_>,
) -> io::Result<()> {
debug_assert_eq!(node.tag_name().name(), "library_images");
for node in node.element_children() {
match node.tag_name().name() {
"image" => {
let image = parse_image(cx, node)?;
cx.library_images.images.insert(image.id, image);
}
"asset" | "extra" => { }
_ => return Err(error::unexpected_child_elem(node)),
}
}
Ok(())
}
fn parse_image<'a>(cx: &Context<'a>, node: xml::Node<'a, '_>) -> io::Result<Image<'a>> {
debug_assert_eq!(node.tag_name().name(), "image");
let id = node.required_attribute("id")?;
let is_1_4 = cx.version.is_1_4();
if is_1_4 {
let _height: Option<u32> = node.parse_attribute("height")?;
let _width: Option<u32> = node.parse_attribute("width")?;
let _depth: u32 = node.parse_attribute("depth")?.unwrap_or(1);
} else {
}
let mut source = None;
for node in node.element_children() {
let tag_name = node.tag_name().name();
match tag_name {
"init_from" => {
if is_1_4 {
source = Some(ImageSource::InitFrom(node.trimmed_text()));
continue;
}
for node in node.element_children() {
match node.tag_name().name() {
"ref" => {
source = Some(ImageSource::InitFrom(node.trimmed_text()));
}
"hex" => {
let data = hex::decode(node.trimmed_text().as_bytes())?;
source = Some(ImageSource::Data(data));
}
_ => {}
}
}
}
"data" if is_1_4 => {
let data = hex::decode(node.trimmed_text().as_bytes())?;
source = Some(ImageSource::Data(data));
}
"asset" | "extra" => { }
_ if is_1_4 => return Err(error::unexpected_child_elem(node)),
_ => {}
}
}
let source = match source {
Some(source) => source,
None => {
if is_1_4 {
bail!(
"<{}> element must be contain <data> or <init_from> element ({})",
node.tag_name().name(),
node.node_location()
)
}
ImageSource::Skip
}
};
Ok(Image {
id,
source,
})
}