rosrust/rosxmlrpc/
client.rs
1use super::error::{ErrorKind, Result, ResultExt};
2use super::{Response, ResponseError, ResponseInfo};
3use serde::{Deserialize, Serialize};
4use xml_rpc::{self, Params, Url, Value};
5
6pub struct Client {
7 master_uri: Url,
8}
9
10impl Client {
11 pub fn new(master_uri: &str) -> Result<Client> {
12 let master_uri = master_uri
13 .parse()
14 .chain_err(|| ErrorKind::BadUri(master_uri.into()))?;
15 Ok(Client { master_uri })
16 }
17
18 pub fn request_tree_with_tree(&self, name: &str, params: Params) -> Response<Value> {
19 let call_result = xml_rpc::call_value(&self.master_uri, name, params);
20
21 let server_response = call_result.map_err(|err| {
22 ResponseError::Client(format!("Failed to perform call to server: {}", err))
23 })?;
24
25 let response_parameters = server_response.map_err(|fault| {
26 ResponseError::Client(format!(
27 "Unexpected fault #{} received from server: {}",
28 fault.code, fault.message
29 ))
30 })?;
31
32 let response_parameters = remove_array_wrappers(&response_parameters[..]);
33
34 ResponseInfo::from_array(response_parameters)?.into()
35 }
36
37 pub fn request_tree<S>(&self, name: &str, params: &S) -> Response<Value>
38 where
39 S: Serialize,
40 {
41 let params = xml_rpc::into_params(params).map_err(bad_request_structure)?;
42 self.request_tree_with_tree(name, params)
43 }
44
45 pub fn request<'a, S, D>(&self, name: &str, params: &S) -> Response<D>
46 where
47 S: Serialize,
48 D: Deserialize<'a>,
49 {
50 let data = self.request_tree(name, params)?;
51 Deserialize::deserialize(data).map_err(bad_response_structure)
52 }
53}
54
55fn remove_array_wrappers(mut data: &[Value]) -> &[Value] {
56 while let [Value::Array(ref children)] = data[..] {
57 data = children;
58 }
59 data
60}
61
62fn bad_request_structure<T: ::std::fmt::Display>(err: T) -> ResponseError {
63 ResponseError::Client(format!("Failed to serialize parameters: {}", err))
64}
65
66pub(crate) fn bad_response_structure<T: ::std::fmt::Display>(err: T) -> ResponseError {
67 ResponseError::Server(format!("Response data has unexpected structure: {}", err))
68}