xrust_net/
resolver.rs

1//! # xrust-net::resolver
2//!
3//! Resolve a URL
4
5use std::fs;
6use std::path::Path;
7use url::Url;
8use xrust::xdmerror::{Error, ErrorKind};
9
10pub fn resolve(url: &Url) -> Result<String, Error> {
11    match url.scheme() {
12        "http" => reqwest::blocking::get(url.to_string())
13            .map_err(|_| {
14                Error::new(
15                    ErrorKind::Unknown,
16                    format!("unable to fetch href URL \"{}\"", url.to_string()),
17                )
18            })?
19            .text()
20            .map_err(|_| {
21                Error::new(
22                    ErrorKind::Unknown,
23                    "unable to extract module data".to_string(),
24                )
25            }),
26        "file" => fs::read_to_string(Path::new(url.path()))
27            .map_err(|er| Error::new(ErrorKind::Unknown, er.to_string())),
28        _ => {
29            return Result::Err(Error::new(
30                ErrorKind::Unknown,
31                format!("unable to fetch URL \"{}\"", url.to_string()),
32            ));
33        }
34    }
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40
41    use xrust::item::{Item, Node, SequenceTrait};
42    use xrust::parser::xml::parse as xmlparse;
43    use xrust::transform::context::StaticContextBuilder;
44    use xrust::trees::smite::RNode;
45    use xrust::xslt::from_document;
46
47    fn make_from_str(s: &str) -> Result<RNode, Error> {
48        let d = RNode::new_document();
49        let _ = xmlparse(d.clone(), s, None)?;
50        Ok(d)
51    }
52
53    #[test]
54    fn include() {
55        let mut sc = StaticContextBuilder::new()
56            .message(|_| Ok(()))
57            .fetcher(|u| resolve(u))
58            .parser(|s| make_from_str(s))
59            .build();
60
61        let src = Item::Node(
62            make_from_str("<Test>one<Level1/>two<Level2/>three<Level3/>four<Level4/></Test>")
63                .expect("unable to parse source document"),
64        );
65
66        let style = make_from_str(
67            "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
68  <xsl:include href='included.xsl'/>
69  <xsl:template match='child::Test'><xsl:apply-templates/></xsl:template>
70  <xsl:template match='child::Level1'>found Level1 element</xsl:template>
71  <xsl:template match='child::text()'><xsl:sequence select='.'/></xsl:template>
72</xsl:stylesheet>",
73        )
74        .expect("unable to parse stylesheet");
75
76        // Setup dynamic context with result document
77        let pwd = std::env::current_dir().expect("unable to get current directory");
78        let pwds = pwd
79            .into_os_string()
80            .into_string()
81            .expect("unable to convert pwd");
82        let mut ctxt = from_document(
83            style,
84            Some(
85                Url::parse(format!("file://{}/tests/xsl/including.xsl", pwds.as_str()).as_str())
86                    .expect("unable to parse URL"),
87            ),
88            |s| make_from_str(s),
89            |url| resolve(url),
90        )
91        .expect("failed to compile stylesheet");
92
93        let rd = RNode::new_document();
94
95        ctxt.context(vec![src], 0);
96        ctxt.result_document(rd.clone());
97
98        let seq = ctxt.evaluate(&mut sc).expect("evaluation failed");
99
100        assert_eq!(
101            seq.to_xml(),
102            "onefound Level1 elementtwofound Level2 elementthreefound Level3 elementfour"
103        )
104    }
105}