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::ParseError;
43    use xrust::parser::xml::parse as xmlparse;
44    use xrust::transform::context::StaticContextBuilder;
45    use xrust::trees::smite::RNode;
46    use xrust::xslt::from_document;
47
48    fn make_from_str(s: &str) -> Result<RNode, Error> {
49        let d = RNode::new_document();
50        let _ = xmlparse(d.clone(), s, Some(|_: &_| Err(ParseError::Notimplemented)))?;
51        Ok(d)
52    }
53
54    #[test]
55    fn include() {
56        let mut sc = StaticContextBuilder::new()
57            .message(|_| Ok(()))
58            .fetcher(|u| resolve(u))
59            .parser(|s| make_from_str(s))
60            .build();
61
62        let src = Item::Node(
63            make_from_str("<Test>one<Level1/>two<Level2/>three<Level3/>four<Level4/></Test>")
64                .expect("unable to parse source document"),
65        );
66
67        let style = make_from_str(
68            "<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
69  <xsl:include href='included.xsl'/>
70  <xsl:template match='child::Test'><xsl:apply-templates/></xsl:template>
71  <xsl:template match='child::Level1'>found Level1 element</xsl:template>
72  <xsl:template match='child::text()'><xsl:sequence select='.'/></xsl:template>
73</xsl:stylesheet>",
74        )
75        .expect("unable to parse stylesheet");
76
77        // Setup dynamic context with result document
78        let pwd = std::env::current_dir().expect("unable to get current directory");
79        let pwds = pwd
80            .into_os_string()
81            .into_string()
82            .expect("unable to convert pwd");
83        let mut ctxt = from_document(
84            style,
85            Some(
86                Url::parse(format!("file://{}/tests/xsl/including.xsl", pwds.as_str()).as_str())
87                    .expect("unable to parse URL"),
88            ),
89            |s| make_from_str(s),
90            |url| resolve(url),
91        )
92        .expect("failed to compile stylesheet");
93
94        let rd = RNode::new_document();
95
96        ctxt.context(vec![src], 0);
97        ctxt.result_document(rd.clone());
98
99        let seq = ctxt.evaluate(&mut sc).expect("evaluation failed");
100
101        assert_eq!(
102            seq.to_xml(),
103            "onefound Level1 elementtwofound Level2 elementthreefound Level3 elementfour"
104        )
105    }
106}