rosrust_codegen/
genmsg.rs
1use crate::error::{Result, ResultExt};
2use crate::helpers;
3use crate::helpers::MessageMap;
4use crate::output_layout;
5use ros_message::MessagePath;
6use std::collections::{HashMap, HashSet};
7use std::convert::TryInto;
8
9pub fn depend_on_messages(
10 ignore_bad_messages: bool,
11 folders: &[&str],
12 messages: &[&str],
13) -> Result<output_layout::Layout> {
14 let message_map = message_names_to_message_map(ignore_bad_messages, folders, messages)?;
15 message_map_to_layout(&message_map)
16}
17
18fn message_names_to_message_map(
19 ignore_bad_messages: bool,
20 folders: &[&str],
21 messages: &[&str],
22) -> Result<MessageMap> {
23 let message_pairs = messages
24 .iter()
25 .copied()
26 .map(TryInto::try_into)
27 .collect::<ros_message::Result<Vec<MessagePath>>>()
28 .chain_err(|| "Failed to parse all message paths")?;
29 helpers::get_message_map(ignore_bad_messages, folders, &message_pairs)
30}
31
32fn message_map_to_layout(message_map: &MessageMap) -> Result<output_layout::Layout> {
33 let mut output = output_layout::Layout {
34 packages: Vec::new(),
35 };
36 let hashes = helpers::calculate_md5(message_map)?;
37 let packages = message_map
38 .messages
39 .keys()
40 .map(|message| message.package().into())
41 .chain(
42 message_map
43 .services
44 .keys()
45 .map(|message| message.package().into()),
46 )
47 .collect::<HashSet<String>>();
48 for package in packages {
49 let mut package_data = output_layout::Package {
50 name: package.clone(),
51 messages: Vec::new(),
52 services: Vec::new(),
53 };
54 let names = message_map
55 .messages
56 .iter()
57 .filter(|&(message, _value)| message.package() == package)
58 .map(|(message, value)| (message.name().into(), value.0.source().into()))
59 .collect::<HashMap<String, String>>();
60 for (name, source) in names {
61 let key = MessagePath::new(&package, name).chain_err(|| "Invalid message path")?;
62 let message = message_map
63 .messages
64 .get(&key)
65 .expect("Internal implementation contains mismatch in map keys")
66 .clone();
67 let md5sum = hashes
68 .get(&key)
69 .expect("Internal implementation contains mismatch in map keys")
70 .clone();
71 let msg_definition =
72 helpers::generate_message_definition(&message_map.messages, &message)?;
73 let msg_type = message.full_name();
74 package_data.messages.push(output_layout::Message {
75 message,
76 msg_definition,
77 msg_type,
78 md5sum,
79 source,
80 });
81 }
82 let names = message_map
83 .services
84 .iter()
85 .filter(|&(message, _value)| message.package() == package)
86 .map(|(message, value)| (message.name().into(), value.source.clone()))
87 .collect::<HashMap<String, String>>();
88 for (name, source) in names {
89 let md5sum = hashes
90 .get(&MessagePath::new(&package, &name).chain_err(|| "Invalid message path")?)
91 .expect("Internal implementation contains mismatch in map keys")
92 .clone();
93 let msg_type = format!("{}/{}", package, name);
94 package_data.services.push(output_layout::Service {
95 name,
96 md5sum,
97 msg_type,
98 source,
99 })
100 }
101 output.packages.push(package_data);
102 }
103 Ok(output)
104}