1use super::super::rosxmlrpc::{self, Response as Result};
2use serde::{Deserialize, Serialize};
3use xml_rpc;
4
5pub struct Master {
6 client: rosxmlrpc::Client,
7 client_id: String,
8 caller_api: String,
9}
10
11macro_rules! request {
12 ($s:expr; $name:ident; $($item:expr),*)=> ({
13 $s.client.request(stringify!($name),&(&$s.client_id,
14 $(
15 $item,
16 )*
17 ))
18 })
19}
20
21macro_rules! request_tree {
22 ($s:expr; $name:ident; $($item:expr),*)=> ({
23 $s.client.request_tree(stringify!($name),&(&$s.client_id,
24 $(
25 $item,
26 )*
27 ))
28 })
29}
30
31impl Master {
32 pub fn new(
33 master_uri: &str,
34 client_id: &str,
35 caller_api: &str,
36 ) -> rosxmlrpc::error::Result<Master> {
37 Ok(Master {
38 client: rosxmlrpc::Client::new(master_uri)?,
39 client_id: client_id.to_owned(),
40 caller_api: caller_api.to_owned(),
41 })
42 }
43
44 pub fn register_service(&self, service: &str, service_api: &str) -> Result<i32> {
45 request!(self; registerService; service, service_api, &self.caller_api)
46 }
47
48 pub fn unregister_service(&self, service: &str, service_api: &str) -> Result<i32> {
49 request!(self; unregisterService; service, service_api)
50 }
51
52 pub fn register_subscriber(&self, topic: &str, topic_type: &str) -> Result<Vec<String>> {
53 request!(self; registerSubscriber; topic, topic_type, &self.caller_api)
54 }
55
56 pub fn unregister_subscriber(&self, topic: &str) -> Result<i32> {
57 request!(self; unregisterSubscriber; topic, &self.caller_api)
58 }
59
60 pub fn register_publisher(&self, topic: &str, topic_type: &str) -> Result<Vec<String>> {
61 request!(self; registerPublisher; topic, topic_type, &self.caller_api)
62 }
63
64 pub fn unregister_publisher(&self, topic: &str) -> Result<i32> {
65 request!(self; unregisterPublisher; topic, &self.caller_api)
66 }
67
68 #[allow(dead_code)]
69 pub fn lookup_node(&self, node_name: &str) -> Result<String> {
70 request!(self; lookupNode; node_name)
71 }
72
73 #[allow(dead_code)]
74 pub fn get_published_topics(&self, subgraph: &str) -> Result<Vec<(String, String)>> {
75 request!(self; getPublishedTopics; subgraph)
76 }
77
78 pub fn get_topic_types(&self) -> Result<Vec<TopicTuple>> {
79 request!(self; getTopicTypes;)
80 }
81
82 pub fn get_system_state(&self) -> Result<SystemStateTuple> {
83 request!(self; getSystemState;)
84 }
85
86 #[allow(dead_code)]
87 pub fn get_uri(&self) -> Result<String> {
88 request!(self; getUri;)
89 }
90
91 pub fn lookup_service(&self, service: &str) -> Result<String> {
92 request!(self; lookupService; service)
93 }
94
95 pub fn delete_param(&self, key: &str) -> Result<i32> {
96 request!(self; deleteParam; key)
97 }
98
99 pub fn set_param<T: Serialize>(&self, key: &str, value: &T) -> Result<i32> {
100 request!(self; setParam; key, value)
101 }
102
103 pub fn set_param_any(&self, key: &str, value: xml_rpc::Value) -> Result<()> {
104 self.client
105 .request_tree_with_tree(
106 "setParam",
107 vec![
108 xml_rpc::Value::String(self.client_id.clone()),
109 xml_rpc::Value::String(key.into()),
110 value,
111 ],
112 )
113 .and(Ok(()))
114 }
115
116 pub fn get_param<'a, T: Deserialize<'a>>(&self, key: &str) -> Result<T> {
117 request!(self; getParam; key)
118 }
119
120 pub fn get_param_any(&self, key: &str) -> Result<xml_rpc::Value> {
121 request_tree!(self; getParam; key)
122 }
123
124 pub fn search_param(&self, key: &str) -> Result<String> {
125 request!(self; searchParam; key)
126 }
127
128 #[allow(dead_code)]
129 pub fn subscribe_param<'a, T: Deserialize<'a>>(&self, key: &str) -> Result<T> {
130 request!(self; subscribeParam; &self.caller_api, key)
131 }
132
133 #[allow(dead_code)]
134 pub fn subscribe_param_any(&self, key: &str) -> Result<xml_rpc::Value> {
135 request_tree!(self; subscribeParam; &self.caller_api, key)
136 }
137
138 #[allow(dead_code)]
139 pub fn unsubscribe_param(&self, key: &str) -> Result<i32> {
140 request!(self; unsubscribeParam; &self.caller_api, key)
141 }
142
143 pub fn has_param(&self, key: &str) -> Result<bool> {
144 request!(self; hasParam; key)
145 }
146
147 pub fn get_param_names(&self) -> Result<Vec<String>> {
148 request!(self; getParamNames;)
149 }
150}
151
152#[derive(Debug)]
153pub struct TopicData {
154 pub name: String,
155 pub connections: Vec<String>,
156}
157
158#[derive(Debug)]
159pub struct SystemState {
160 pub publishers: Vec<TopicData>,
161 pub subscribers: Vec<TopicData>,
162 pub services: Vec<TopicData>,
163}
164
165#[derive(Debug, serde_derive::Deserialize)]
166pub struct TopicDataTuple(String, Vec<String>);
167#[derive(Debug, serde_derive::Deserialize)]
168pub struct SystemStateTuple(
169 Vec<TopicDataTuple>,
170 Vec<TopicDataTuple>,
171 Vec<TopicDataTuple>,
172);
173
174impl From<SystemStateTuple> for SystemState {
175 fn from(src: SystemStateTuple) -> SystemState {
176 SystemState {
177 publishers: src.0.into_iter().map(Into::into).collect(),
178 subscribers: src.1.into_iter().map(Into::into).collect(),
179 services: src.2.into_iter().map(Into::into).collect(),
180 }
181 }
182}
183
184impl From<TopicDataTuple> for TopicData {
185 fn from(src: TopicDataTuple) -> TopicData {
186 TopicData {
187 name: src.0,
188 connections: src.1,
189 }
190 }
191}
192
193#[derive(Debug, serde_derive::Deserialize)]
194pub struct TopicTuple(String, String);
195
196impl From<TopicTuple> for Topic {
197 fn from(src: TopicTuple) -> Topic {
198 Topic {
199 name: src.0,
200 datatype: src.1,
201 }
202 }
203}
204
205pub struct Topic {
206 pub name: String,
207 pub datatype: String,
208}