xml-sec 0.1.23

Pure Rust XML Security: XMLDSig, XMLEnc, C14N. Drop-in replacement for libxmlsec1.
Documentation
//! Prepared backend DOMs for measuring the real projection independently.

use super::{Document, LexicalPreflight, ParseError, ParsingOptions, XmlBackend};
use crate::{parser_roxmltree, parser_xmloxide};

enum Parsed<'a> {
    Roxmltree(parser_roxmltree::Document<'a>),
    Xmloxide(parser_xmloxide::Document),
}

pub(crate) struct Projection<'a> {
    input: &'a str,
    preflight: LexicalPreflight<'a>,
    parsed: Parsed<'a>,
}

impl<'a> Projection<'a> {
    pub(crate) fn new(input: &'a str, backend: XmlBackend) -> Result<Self, ParseError> {
        let preflight = LexicalPreflight::scan(input, false)?;
        let parsed = match backend {
            XmlBackend::Roxmltree => {
                Parsed::Roxmltree(parser_roxmltree::Document::parse(input).map_err(|e| {
                    ParseError::Backend {
                        backend: "roxmltree",
                        message: e.to_string(),
                    }
                })?)
            }
            XmlBackend::Xmloxide => Parsed::Xmloxide(
                parser_xmloxide::parser::parse_str_with_options(
                    input,
                    &super::xmloxide::backend_options(),
                )
                .map_err(|e| ParseError::Backend {
                    backend: "xmloxide",
                    message: e.to_string(),
                })?,
            ),
            XmlBackend::Differential => return Err(ParseError::BackendUnavailable { backend }),
        };
        Ok(Self {
            input,
            preflight,
            parsed,
        })
    }

    pub(crate) fn project(&self) -> Result<Document<'a>, ParseError> {
        match &self.parsed {
            Parsed::Roxmltree(parsed) => {
                super::roxmltree::project(self.input, parsed, &self.preflight)
            }
            Parsed::Xmloxide(parsed) => super::xmloxide::project(
                self.input,
                parsed,
                ParsingOptions::default(),
                &self.preflight,
            ),
        }
    }
}