rosrust 0.9.10

Pure Rust implementation of a ROS client library
Documentation
use super::super::rosxmlrpc::{self, Response as Result};
use serde::{Deserialize, Serialize};
use xml_rpc;

pub struct Master {
    client: rosxmlrpc::Client,
    client_id: String,
    caller_api: String,
}

macro_rules! request {
    ($s:expr; $name:ident; $($item:expr),*)=> ({
        $s.client.request(stringify!($name),&(&$s.client_id,
            $(
                $item,
            )*
            ))
    })
}

macro_rules! request_tree {
    ($s:expr; $name:ident; $($item:expr),*)=> ({
        $s.client.request_tree(stringify!($name),&(&$s.client_id,
            $(
                $item,
            )*
            ))
    })
}

impl Master {
    pub fn new(
        master_uri: &str,
        client_id: &str,
        caller_api: &str,
    ) -> rosxmlrpc::error::Result<Master> {
        Ok(Master {
            client: rosxmlrpc::Client::new(master_uri)?,
            client_id: client_id.to_owned(),
            caller_api: caller_api.to_owned(),
        })
    }

    pub fn register_service(&self, service: &str, service_api: &str) -> Result<i32> {
        request!(self; registerService; service, service_api, &self.caller_api)
    }

    pub fn unregister_service(&self, service: &str, service_api: &str) -> Result<i32> {
        request!(self; unregisterService; service, service_api)
    }

    pub fn register_subscriber(&self, topic: &str, topic_type: &str) -> Result<Vec<String>> {
        request!(self; registerSubscriber; topic, topic_type, &self.caller_api)
    }

    pub fn unregister_subscriber(&self, topic: &str) -> Result<i32> {
        request!(self; unregisterSubscriber; topic, &self.caller_api)
    }

    pub fn register_publisher(&self, topic: &str, topic_type: &str) -> Result<Vec<String>> {
        request!(self; registerPublisher; topic, topic_type, &self.caller_api)
    }

    pub fn unregister_publisher(&self, topic: &str) -> Result<i32> {
        request!(self; unregisterPublisher; topic, &self.caller_api)
    }

    #[allow(dead_code)]
    pub fn lookup_node(&self, node_name: &str) -> Result<String> {
        request!(self; lookupNode; node_name)
    }

    #[allow(dead_code)]
    pub fn get_published_topics(&self, subgraph: &str) -> Result<Vec<(String, String)>> {
        request!(self; getPublishedTopics; subgraph)
    }

    pub fn get_topic_types(&self) -> Result<Vec<TopicTuple>> {
        request!(self; getTopicTypes;)
    }

    pub fn get_system_state(&self) -> Result<SystemStateTuple> {
        request!(self; getSystemState;)
    }

    #[allow(dead_code)]
    pub fn get_uri(&self) -> Result<String> {
        request!(self; getUri;)
    }

    pub fn lookup_service(&self, service: &str) -> Result<String> {
        request!(self; lookupService; service)
    }

    pub fn delete_param(&self, key: &str) -> Result<i32> {
        request!(self; deleteParam; key)
    }

    pub fn set_param<T: Serialize>(&self, key: &str, value: &T) -> Result<i32> {
        request!(self; setParam; key, value)
    }

    pub fn set_param_any(&self, key: &str, value: xml_rpc::Value) -> Result<()> {
        self.client
            .request_tree_with_tree(
                "setParam",
                vec![
                    xml_rpc::Value::String(self.client_id.clone()),
                    xml_rpc::Value::String(key.into()),
                    value,
                ],
            )
            .and(Ok(()))
    }

    pub fn get_param<'a, T: Deserialize<'a>>(&self, key: &str) -> Result<T> {
        request!(self; getParam; key)
    }

    pub fn get_param_any(&self, key: &str) -> Result<xml_rpc::Value> {
        request_tree!(self; getParam; key)
    }

    pub fn search_param(&self, key: &str) -> Result<String> {
        request!(self; searchParam; key)
    }

    #[allow(dead_code)]
    pub fn subscribe_param<'a, T: Deserialize<'a>>(&self, key: &str) -> Result<T> {
        request!(self; subscribeParam; &self.caller_api, key)
    }

    #[allow(dead_code)]
    pub fn subscribe_param_any(&self, key: &str) -> Result<xml_rpc::Value> {
        request_tree!(self; subscribeParam; &self.caller_api, key)
    }

    #[allow(dead_code)]
    pub fn unsubscribe_param(&self, key: &str) -> Result<i32> {
        request!(self; unsubscribeParam; &self.caller_api, key)
    }

    pub fn has_param(&self, key: &str) -> Result<bool> {
        request!(self; hasParam; key)
    }

    pub fn get_param_names(&self) -> Result<Vec<String>> {
        request!(self; getParamNames;)
    }
}

#[derive(Debug)]
pub struct TopicData {
    pub name: String,
    pub connections: Vec<String>,
}

#[derive(Debug)]
pub struct SystemState {
    pub publishers: Vec<TopicData>,
    pub subscribers: Vec<TopicData>,
    pub services: Vec<TopicData>,
}

#[derive(Debug, serde_derive::Deserialize)]
pub struct TopicDataTuple(String, Vec<String>);
#[derive(Debug, serde_derive::Deserialize)]
pub struct SystemStateTuple(
    Vec<TopicDataTuple>,
    Vec<TopicDataTuple>,
    Vec<TopicDataTuple>,
);

impl From<SystemStateTuple> for SystemState {
    fn from(src: SystemStateTuple) -> SystemState {
        SystemState {
            publishers: src.0.into_iter().map(Into::into).collect(),
            subscribers: src.1.into_iter().map(Into::into).collect(),
            services: src.2.into_iter().map(Into::into).collect(),
        }
    }
}

impl From<TopicDataTuple> for TopicData {
    fn from(src: TopicDataTuple) -> TopicData {
        TopicData {
            name: src.0,
            connections: src.1,
        }
    }
}

#[derive(Debug, serde_derive::Deserialize)]
pub struct TopicTuple(String, String);

impl From<TopicTuple> for Topic {
    fn from(src: TopicTuple) -> Topic {
        Topic {
            name: src.0,
            datatype: src.1,
        }
    }
}

pub struct Topic {
    pub name: String,
    pub datatype: String,
}