File: xml.rs

package info (click to toggle)
rust-ognibuild 0.2.7-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,616 kB
  • sloc: makefile: 17
file content (141 lines) | stat: -rw-r--r-- 4,462 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! Support for XML entity dependencies.
//!
//! This module provides functionality for working with XML entity dependencies,
//! including checking if entities are defined in the local XML catalog and
//! mapping between URLs and filesystem paths.

use crate::dependencies::Dependency;
use crate::session::Session;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
/// A dependency on an XML entity, such as a DocBook DTD.
///
/// This represents a dependency on an XML entity, which is typically resolved
/// through an XML catalog.
pub struct XmlEntityDependency {
    url: String,
}

impl XmlEntityDependency {
    /// Create a new XML entity dependency with the specified URL.
    ///
    /// # Arguments
    /// * `url` - The URL of the XML entity
    ///
    /// # Returns
    /// A new XmlEntityDependency
    pub fn new(url: &str) -> Self {
        Self {
            url: url.to_string(),
        }
    }
}

impl Dependency for XmlEntityDependency {
    fn family(&self) -> &'static str {
        "xml-entity"
    }

    fn present(&self, session: &dyn Session) -> bool {
        // Check if the entity is defined in the local XML catalog
        session
            .command(vec!["xmlcatalog", "--noout", "--resolve", &self.url])
            .stdout(std::process::Stdio::null())
            .stderr(std::process::Stdio::null())
            .run()
            .unwrap()
            .success()
    }

    fn project_present(&self, _session: &dyn Session) -> bool {
        todo!()
    }
    fn as_any(&self) -> &dyn std::any::Any {
        self
    }
}

/// Mapping between XML entity URLs and their filesystem locations.
///
/// This constant maps from entity URLs to their corresponding filesystem paths,
/// which is used to locate entities when resolving dependencies.
pub const XML_ENTITY_URL_MAP: &[(&str, &str)] = &[(
    "http://www.oasis-open.org/docbook/xml/",
    "/usr/share/xml/docbook/schema/dtd/",
)];

#[cfg(feature = "debian")]
impl crate::dependencies::debian::IntoDebianDependency for XmlEntityDependency {
    fn try_into_debian_dependency(
        &self,
        apt: &crate::debian::apt::AptManager,
    ) -> std::option::Option<std::vec::Vec<crate::dependencies::debian::DebianDependency>> {
        let path = XML_ENTITY_URL_MAP.iter().find_map(|(url, path)| {
            self.url
                .strip_prefix(url)
                .map(|rest| format!("{}{}", path, rest))
        });

        path.as_ref()?;

        Some(
            apt.get_packages_for_paths(vec![path.as_ref().unwrap()], false, false)
                .unwrap()
                .iter()
                .map(|p| crate::dependencies::debian::DebianDependency::simple(p.as_str()))
                .collect(),
        )
    }
}

impl crate::buildlog::ToDependency for buildlog_consultant::problems::common::MissingXmlEntity {
    fn to_dependency(&self) -> Option<Box<dyn Dependency>> {
        Some(Box::new(XmlEntityDependency::new(&self.url)))
    }
}

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

    #[test]
    fn test_xml_entity_dependency_new() {
        let url = "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd";
        let dependency = XmlEntityDependency::new(url);
        assert_eq!(dependency.url, url);
    }

    #[test]
    fn test_xml_entity_dependency_family() {
        let dependency = XmlEntityDependency::new("http://www.example.com/entity");
        assert_eq!(dependency.family(), "xml-entity");
    }

    #[test]
    fn test_xml_entity_dependency_as_any() {
        let dependency = XmlEntityDependency::new("http://www.example.com/entity");
        let any_dep: &dyn Any = dependency.as_any();
        assert!(any_dep.downcast_ref::<XmlEntityDependency>().is_some());
    }

    #[test]
    fn test_xml_entity_url_map() {
        assert!(XML_ENTITY_URL_MAP
            .iter()
            .any(|(url, _)| *url == "http://www.oasis-open.org/docbook/xml/"));

        // Test that the URL map can be used to transform URLs
        let input_url = "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd";
        let expected_path = "/usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd";

        let transformed = XML_ENTITY_URL_MAP.iter().find_map(|(url, path)| {
            input_url
                .strip_prefix(url)
                .map(|rest| format!("{}{}", path, rest))
        });

        assert_eq!(transformed, Some(expected_path.to_string()));
    }
}