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 let manifest: Manifest = Manifest::from_path("./Cargo.toml")?;
11
12 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 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())?; writer.write(XmlEvent::end_element())?; 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}