xrust-net 0.2.2

Support for Xrust
Documentation
//! # xrust-net::resolver
//!
//! Resolve a URL

use std::fs;
use std::path::Path;
use url::Url;
use xrust::xdmerror::{Error, ErrorKind};

pub fn resolve(url: &Url) -> Result<String, Error> {
    match url.scheme() {
        "http" => reqwest::blocking::get(url.to_string())
            .map_err(|_| {
                Error::new(
                    ErrorKind::Unknown,
                    format!("unable to fetch href URL \"{}\"", url.to_string()),
                )
            })?
            .text()
            .map_err(|_| {
                Error::new(
                    ErrorKind::Unknown,
                    "unable to extract module data".to_string(),
                )
            }),
        "file" => fs::read_to_string(Path::new(url.path()))
            .map_err(|er| Error::new(ErrorKind::Unknown, er.to_string())),
        _ => {
            return Result::Err(Error::new(
                ErrorKind::Unknown,
                format!("unable to fetch URL \"{}\"", url.to_string()),
            ));
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use xrust::item::{Item, Node, SequenceTrait};
    use xrust::parser::ParseError;
    use xrust::parser::xml::parse as xmlparse;
    use xrust::transform::context::StaticContextBuilder;
    use xrust::trees::smite::RNode;
    use xrust::xslt::from_document;

    fn make_from_str(s: &str) -> Result<RNode, Error> {
        let d = RNode::new_document();
        let _ = xmlparse(d.clone(), s, Some(|_: &_| Err(ParseError::Notimplemented)))?;
        Ok(d)
    }

    #[test]
    fn include() {
        let mut sc = StaticContextBuilder::new()
            .message(|_| Ok(()))
            .fetcher(|u| resolve(u))
            .parser(|s| make_from_str(s))
            .build();

        let src = Item::Node(
            make_from_str("<Test>one<Level1/>two<Level2/>three<Level3/>four<Level4/></Test>")
                .expect("unable to parse source document"),
        );

        let style = make_from_str(
            "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
  <xsl:include href='included.xsl'/>
  <xsl:template match='child::Test'><xsl:apply-templates/></xsl:template>
  <xsl:template match='child::Level1'>found Level1 element</xsl:template>
  <xsl:template match='child::text()'><xsl:sequence select='.'/></xsl:template>
</xsl:stylesheet>",
        )
        .expect("unable to parse stylesheet");

        // Setup dynamic context with result document
        let pwd = std::env::current_dir().expect("unable to get current directory");
        let pwds = pwd
            .into_os_string()
            .into_string()
            .expect("unable to convert pwd");
        let mut ctxt = from_document(
            style,
            Some(
                Url::parse(format!("file://{}/tests/xsl/including.xsl", pwds.as_str()).as_str())
                    .expect("unable to parse URL"),
            ),
            |s| make_from_str(s),
            |url| resolve(url),
        )
        .expect("failed to compile stylesheet");

        let rd = RNode::new_document();

        ctxt.context(vec![src], 0);
        ctxt.result_document(rd.clone());

        let seq = ctxt.evaluate(&mut sc).expect("evaluation failed");

        assert_eq!(
            seq.to_xml(),
            "onefound Level1 elementtwofound Level2 elementthreefound Level3 elementfour"
        )
    }
}