ros2_pkginfogen/
lib.rs

1use std::fs::File;
2use std::io::{BufWriter, Write};
3use std::path::Path;
4
5use cargo_toml::{Inheritable, Manifest};
6use xml::writer::{EmitterConfig, XmlEvent};
7
8pub fn generate_string(path: &Path) -> Result<(), Box<dyn std::error::Error>> {
9    // Parse Cargo.toml
10    let manifest: Manifest = Manifest::from_path("./Cargo.toml")?;
11
12    // Open file to write XML
13    let file = File::create(path)?;
14    let mut file = BufWriter::new(file);
15    writeln!(
16        file,
17        r#"<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>"#
18    ).unwrap();
19    let mut writer = EmitterConfig::new()
20        .perform_indent(true)
21        .create_writer(file);
22
23    let package = manifest.package.unwrap();
24    let package_name = &package.name;
25    let version = package.version.as_ref().unwrap();
26    let description = package.description;
27    let authors = package.authors.as_ref().unwrap();
28    let license = package.license;
29
30    // Extract the author's name and email from the first author in the list
31    let (maintainer_name, maintainer_email) = if let Some(author) = authors.get(0) {
32        let parts: Vec<&str> = author.split('<').collect();
33        (
34            parts[0].trim().to_string(),
35            parts[1].trim_end_matches('>').to_string(),
36        )
37    } else {
38        (String::from("Unknown"), String::from("unknown@example.com"))
39    };
40
41    writer.write(XmlEvent::start_element("package").attr("format", "3"))?;
42    writer.write(XmlEvent::start_element("name"))?;
43    writer.write(XmlEvent::characters(&package_name))?;
44    writer.write(XmlEvent::end_element())?;
45
46    writer.write(XmlEvent::start_element("version"))?;
47    writer.write(XmlEvent::characters(&version))?;
48    writer.write(XmlEvent::end_element())?;
49
50    if let Some(Inheritable::Set(ref d)) = description {
51        writer.write(XmlEvent::start_element("description"))?;
52        writer.write(XmlEvent::characters(d))?;
53        writer.write(XmlEvent::end_element())?;
54    }
55
56    writer.write(XmlEvent::start_element("maintainer").attr("email", &maintainer_email))?;
57    writer.write(XmlEvent::characters(&maintainer_name))?;
58    writer.write(XmlEvent::end_element())?;
59
60    if let Some(Inheritable::Set(ref l)) = license {
61        writer.write(XmlEvent::start_element("license"))?;
62        writer.write(XmlEvent::characters(l))?;
63        writer.write(XmlEvent::end_element())?;
64    }
65
66    if let Some(ref deps) = package.metadata {
67        if let Some(value) =  deps.get("ros").unwrap().get("msg") {
68            for name in value.as_array().unwrap() {
69                writer.write(XmlEvent::start_element("depend"))?;
70                writer.write(XmlEvent::characters(name.as_str().unwrap()))?;
71                writer.write(XmlEvent::end_element())?;
72            }
73        }
74    }
75
76    writer.write(XmlEvent::start_element("test_depend"))?;
77    writer.write(XmlEvent::characters("ament_lint_auto"))?;
78    writer.write(XmlEvent::end_element())?;
79
80    writer.write(XmlEvent::start_element("test_depend"))?;
81    writer.write(XmlEvent::characters("ament_lint_common"))?;
82    writer.write(XmlEvent::end_element())?;
83
84    writer.write(XmlEvent::start_element("export"))?;
85    writer.write(XmlEvent::start_element("build_type"))?;
86    writer.write(XmlEvent::characters("ament_cargo"))?;
87    writer.write(XmlEvent::end_element())?;
88    writer.write(XmlEvent::end_element())?; // end of export
89
90    writer.write(XmlEvent::end_element())?; // end of package
91
92    Ok(())
93}
94
95mod tests {
96    use crate::generate_string;
97
98    #[test]
99    pub fn test_func() {
100        generate_string("./package.xml".as_ref()).unwrap()
101    }
102}