1use 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 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}