maven_rs/
default_impl.rs

1use crate::*;
2pub struct DefaultUrlFetcher {}
3
4impl UrlFetcher for DefaultUrlFetcher {
5    fn fetch(&self, url: &str) -> Result<String, ResolverError> {
6        let text = ureq::get(url.into())
7            .call()
8            .map_err(|_| ResolverError::file_not_found(url))?
9            .into_string();
10        Ok(text.unwrap())
11    }
12    fn fetch_bytes(&self, url: &str) -> Result<bytes::Bytes, ResolverError> {
13        let mut data = vec![];
14        ureq::get(url.into())
15            .call()
16            .map_err(|_| ResolverError::file_not_found(url))?
17            .into_reader()
18            .read_to_end(&mut data)
19            .unwrap();
20        Ok(data.into())
21    }
22}
23
24fn node<'a, 'input: 'a>(
25    parent: &'input roxmltree::Node,
26    tag_name: &'a str,
27) -> Option<roxmltree::Node<'a, 'input>> {
28    parent
29        .children()
30        .find(|child| child.is_element() && child.has_tag_name(tag_name))
31}
32
33fn node_text<'a, 'input: 'a>(parent: &'input roxmltree::Node, tag_name: &'a str) -> Option<String> {
34    let n = node(parent, tag_name)?;
35    n.text().map(|t| t.to_owned())
36}
37
38fn parse_gav(n: &roxmltree::Node) -> Artifact {
39    Artifact {
40        group_id: node_text(n, "groupId"),
41        artifact_id: node_text(n, "artifactId"),
42        version: node_text(n, "version"),
43        packaging: node_text(n, "type").or_else(|| node_text(n, "packaging")), // TODO dirty hack
44        classifier: node_text(n, "classifier"),
45    }
46}
47
48fn parse_parent(n: &roxmltree::Node) -> Option<Parent> {
49    let n = node(n, "parent")?;
50    Some(Parent {
51        artifact_fqn: parse_gav(&n),
52    })
53}
54
55fn parse_dependency(n: &roxmltree::Node) -> Dependency {
56    Dependency {
57        artifact_fqn: parse_gav(n),
58        scope: node_text(n, "scope"),
59    }
60}
61
62fn parse_dependencies(n: &roxmltree::Node) -> HashMap<DependencyKey, Dependency> {
63    match node(n, "dependencies") {
64        Some(n) => n
65            .children()
66            .filter(|child| child.is_element() && child.has_tag_name("dependency"))
67            .map(|child| {
68                let dep = parse_dependency(&child);
69                (dep.get_key(), dep)
70            })
71            .collect(),
72        _ => HashMap::new(),
73    }
74}
75
76fn parse_dependency_management(n: &roxmltree::Node) -> Option<DependencyManagement> {
77    node(n, "dependencyManagement").map(|n| DependencyManagement {
78        dependencies: parse_dependencies(&n),
79    })
80}
81
82pub struct DefaultPomParser {}
83
84impl PomParser for DefaultPomParser {
85    fn parse(&self, input: String) -> Result<Project, ResolverError> {
86        let doc = roxmltree::Document::parse(&input).unwrap();
87
88        let n = doc.root();
89        let project_node = node(&n, "project")
90            .ok_or_else(|| ResolverError::invalid_data("invalid XML content, no <project> tag"))?;
91
92        Ok(Project {
93            artifact_fqn: parse_gav(&project_node),
94            parent: parse_parent(&project_node),
95            dependency_management: parse_dependency_management(&project_node),
96            dependencies: parse_dependencies(&project_node),
97            properties: HashMap::new(),
98        })
99    }
100}