Error type which is simply copy paste:d from the generated bindings

This commit is contained in:
Martin Dahl 2019-08-29 11:50:20 +02:00
parent 8ec9d1bedb
commit 321068aa1b
10 changed files with 196 additions and 61 deletions

View File

@ -10,6 +10,8 @@ edition = "2018"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
failure = "0.1.5"
failure_derive = "0.1.5"
common = { path = "common", version = "0.0.1" }
rcl = { path = "rcl", version = "0.0.1" }
msg_gen = { path = "msg_gen", version = "0.0.1" }

View File

@ -2,8 +2,9 @@ use r2r::*;
use builtin_interfaces::msg::Duration;
use trajectory_msgs::msg::*;
use std_msgs::msg::Int32;
use failure::Error;
fn main() -> Result<(), ()> {
fn main() -> Result<(), Error> {
let ctx = Context::create()?;
let mut node = Node::create(ctx, "testnode", "")?;
let publisher = node.create_publisher::<JointTrajectoryPoint>("/hej")?;
@ -30,7 +31,7 @@ fn main() -> Result<(), ()> {
let cb2 = move |x:JointTrajectoryPoint| {
let serialized = serde_json::to_string(&x).unwrap();
println!("JTP serialized as: {}", serialized);
};
};
let cb3 = move |raw_c:&WrappedNativeMsg<JointTrajectoryPoint>| {
println!("Raw c data: {:?}", raw_c.positions);
@ -45,7 +46,8 @@ fn main() -> Result<(), ()> {
// run for 10 seconds
let mut count = 0;
while count < 100 {
// while count < 100 {
loop {
node.spin_once(std::time::Duration::from_millis(100));
count += 1;
}
@ -54,4 +56,3 @@ fn main() -> Result<(), ()> {
Ok(())
}

View File

@ -2,8 +2,9 @@ use r2r::*;
use std::thread;
use std::env;
use std::collections::HashMap;
use failure::Error;
fn main() -> Result<(), ()> {
fn main() -> Result<(), Error> {
let ctx = Context::create()?;
let mut node = Node::create(ctx, "echo", "")?;
@ -25,7 +26,7 @@ fn main() -> Result<(), ()> {
Some(tn) => tn,
None => {
eprintln!("Could not determine the type for the passed topic");
return Err(());
return Ok(());
},
};

View File

@ -1,8 +1,9 @@
use r2r;
use std::thread;
use std::time::Duration;
use failure::Error;
fn main() -> Result<(), ()> {
fn main() -> Result<(), Error> {
let ctx = r2r::Context::create()?;
let node = r2r::Node::create(ctx, "testnode", "")?;

View File

@ -1,8 +1,9 @@
use r2r::*;
use std::sync::mpsc;
use std::thread;
use failure::Error;
fn main() -> Result<(), ()> {
fn main() -> Result<(), Error> {
let ctx = Context::create()?;
let th = {

View File

@ -1,9 +1,10 @@
use std::sync::mpsc;
use std::thread;
use failure::Error;
use r2r::*;
fn main() -> Result<(), ()> {
fn main() -> Result<(), Error> {
let ctx = Context::create()?;
let mut node = Node::create(ctx, "testnode", "")?;

View File

@ -192,37 +192,36 @@ pub fn generate_rust_msg(module_: &str, prefix_: &str, name_: &str) -> String {
// this is even worse, it was added as an afterthought when I wanted to implement rostopic echo
pub fn generate_untyped_helpers(msgs: &Vec<common::RosMsg>) -> String {
let mut ts_helper = format!("fn untyped_ts_helper(typename: &str) -> Result<&'static rosidl_message_type_support_t, ()> {{");
let mut ts_helper = format!("fn untyped_ts_helper(typename: &str) -> Result<&'static rosidl_message_type_support_t> {{");
for msg in msgs {
ts_helper.push_str(&generate_untyped_ts_helper(&msg.module, &msg.prefix, &msg.name));
}
ts_helper.push_str(&format!("return Err(())\n}}"));
ts_helper.push_str(&format!("return Err(Error::InvalidMessageType{{ msgtype: typename.into() }})\n}}"));
let mut ds_helper = format!("fn untyped_deserialize_helper(typename: &str) -> Result<fn(native: *const std::os::raw::c_void) -> serde_json::Value, ()> {{");
let mut ds_helper = format!("fn untyped_deserialize_helper(typename: &str) -> Result<fn(native: *const std::os::raw::c_void) -> serde_json::Value> {{");
for msg in msgs {
ds_helper.push_str(&generate_untyped_deserialize_helper(&msg.module, &msg.prefix, &msg.name));
}
ds_helper.push_str(&format!("return Err(())\n}}"));
ds_helper.push_str(&format!("return Err(Error::InvalidMessageType{{ msgtype: typename.into() }})\n}}"));
let mut se_helper = format!("
fn untyped_serialize_helper(typename: &str) -> Result<fn(json: serde_json::Value) -> Result<*mut std::os::raw::c_void, ()>, ()> {{");
fn untyped_serialize_helper(typename: &str) -> Result<fn(json: serde_json::Value) -> std::result::Result<*mut std::os::raw::c_void, serde_json::error::Error>> {{");
for msg in msgs {
se_helper.push_str(&generate_untyped_serialize_helper(&msg.module, &msg.prefix, &msg.name));
}
se_helper.push_str(&format!("return Err(())\n}}"));
se_helper.push_str(&format!("return Err(Error::InvalidMessageType{{ msgtype: typename.into() }})\n}}"));
let mut alloc_helper = format!("fn untyped_alloc_helper(typename: &str) -> Result<*mut std::os::raw::c_void, ()> {{");
let mut alloc_helper = format!("fn untyped_alloc_helper(typename: &str) -> Result<*mut std::os::raw::c_void> {{");
for msg in msgs {
alloc_helper.push_str(&generate_untyped_alloc_helper(&msg.module, &msg.prefix, &msg.name));
}
alloc_helper.push_str(&format!("return Err(())\n}}"));
alloc_helper.push_str(&format!("return Err(Error::InvalidMessageType{{ msgtype: typename.into() }})\n}}"));
let mut dealloc_helper = format!("fn untyped_dealloc_helper(typename: &str) -> Result<fn(*mut std::os::raw::c_void), ()> {{");
let mut dealloc_helper = format!("fn untyped_dealloc_helper(typename: &str) -> Result<fn(*mut std::os::raw::c_void)> {{");
for msg in msgs {
dealloc_helper.push_str(&generate_untyped_dealloc_helper(&msg.module, &msg.prefix, &msg.name));
}
dealloc_helper.push_str(&format!("return Err(())\n}}"));
dealloc_helper.push_str(&format!("return Err(Error::InvalidMessageType{{ msgtype: typename.into() }})\n}}"));
format!("{} \n\n {} \n\n {} \n\n {} \n\n {} \n\n", ts_helper, ds_helper, se_helper, alloc_helper, dealloc_helper)
}
@ -261,15 +260,10 @@ pub fn generate_untyped_serialize_helper(module_: &str, prefix_: &str, name_: &s
format!("
if typename == \"{typename}\" {{
let x = | json: serde_json::Value | {{
let msg: Result<{rustname}, _> = serde_json::from_value(json);
match msg {{
Ok(msg) => {{
serde_json::from_value(json).map(|msg: {rustname}| {{
let native = {rustname}::create_msg();
unsafe {{ msg.copy_to_native(&mut *native); }}
Ok(native as *mut std::os::raw::c_void)
}},
Err(_) => Err(())
}}
native as *mut std::os::raw::c_void }})
}};
return Ok(x);
}}", typename = typename, rustname = rustname)

126
src/error.rs Normal file
View File

@ -0,0 +1,126 @@
#![allow(non_camel_case_types)]
use rcl::*;
// TODO
#[derive(Debug, Fail)]
pub enum Error {
// Copied from the generated bindgen
#[fail(display = "RCL_RET_OK")]
RCL_RET_OK,
#[fail(display = "RCL_RET_ERROR")]
RCL_RET_ERROR,
#[fail(display = "RCL_RET_TIMEOUT")]
RCL_RET_TIMEOUT,
#[fail(display = "RCL_RET_BAD_ALLOC")]
RCL_RET_BAD_ALLOC,
#[fail(display = "RCL_RET_INVALID_ARGUMENT")]
RCL_RET_INVALID_ARGUMENT,
#[fail(display = "RCL_RET_UNSUPPORTED")]
RCL_RET_UNSUPPORTED,
#[fail(display = "RCL_RET_ALREADY_INIT")]
RCL_RET_ALREADY_INIT,
#[fail(display = "RCL_RET_NOT_INIT")]
RCL_RET_NOT_INIT,
#[fail(display = "RCL_RET_MISMATCHED_RMW_ID")]
RCL_RET_MISMATCHED_RMW_ID,
#[fail(display = "RCL_RET_TOPIC_NAME_INVALID")]
RCL_RET_TOPIC_NAME_INVALID,
#[fail(display = "RCL_RET_SERVICE_NAME_INVALID")]
RCL_RET_SERVICE_NAME_INVALID,
#[fail(display = "RCL_RET_UNKNOWN_SUBSTITUTION")]
RCL_RET_UNKNOWN_SUBSTITUTION,
#[fail(display = "RCL_RET_ALREADY_SHUTDOWN")]
RCL_RET_ALREADY_SHUTDOWN,
#[fail(display = "RCL_RET_NODE_INVALID")]
RCL_RET_NODE_INVALID,
#[fail(display = "RCL_RET_NODE_INVALID_NAME")]
RCL_RET_NODE_INVALID_NAME,
#[fail(display = "RCL_RET_NODE_INVALID_NAMESPACE")]
RCL_RET_NODE_INVALID_NAMESPACE,
#[fail(display = "RCL_RET_PUBLISHER_INVALID")]
RCL_RET_PUBLISHER_INVALID,
#[fail(display = "RCL_RET_SUBSCRIPTION_INVALID")]
RCL_RET_SUBSCRIPTION_INVALID,
#[fail(display = "RCL_RET_SUBSCRIPTION_TAKE_FAILED")]
RCL_RET_SUBSCRIPTION_TAKE_FAILED,
#[fail(display = "RCL_RET_CLIENT_INVALID")]
RCL_RET_CLIENT_INVALID,
#[fail(display = "RCL_RET_CLIENT_TAKE_FAILED")]
RCL_RET_CLIENT_TAKE_FAILED,
#[fail(display = "RCL_RET_SERVICE_INVALID")]
RCL_RET_SERVICE_INVALID,
#[fail(display = "RCL_RET_SERVICE_TAKE_FAILED")]
RCL_RET_SERVICE_TAKE_FAILED,
#[fail(display = "RCL_RET_TIMER_INVALID")]
RCL_RET_TIMER_INVALID,
#[fail(display = "RCL_RET_TIMER_CANCELED")]
RCL_RET_TIMER_CANCELED,
#[fail(display = "RCL_RET_WAIT_SET_INVALID")]
RCL_RET_WAIT_SET_INVALID,
#[fail(display = "RCL_RET_WAIT_SET_EMPTY")]
RCL_RET_WAIT_SET_EMPTY,
#[fail(display = "RCL_RET_WAIT_SET_FULL")]
RCL_RET_WAIT_SET_FULL,
#[fail(display = "RCL_RET_INVALID_REMAP_RULE")]
RCL_RET_INVALID_REMAP_RULE,
#[fail(display = "RCL_RET_WRONG_LEXEME")]
RCL_RET_WRONG_LEXEME,
#[fail(display = "RCL_RET_INVALID_PARAM_RULE")]
RCL_RET_INVALID_PARAM_RULE,
#[fail(display = "RCL_RET_INVALID_LOG_LEVEL_RULE")]
RCL_RET_INVALID_LOG_LEVEL_RULE,
#[fail(display = "RCL_RET_EVENT_INVALID")]
RCL_RET_EVENT_INVALID,
#[fail(display = "RCL_RET_EVENT_TAKE_FAILED")]
RCL_RET_EVENT_TAKE_FAILED,
// Our own errors
#[fail(display = "No typesupport build for the message type: {}", msgtype)]
InvalidMessageType { msgtype: String },
#[fail(display = "Serde error: {}", err)]
SerdeError { err: String },
}
impl Error {
pub fn from_rcl_error(e: i32) -> Self {
let e = e as u32;
match e {
_ if e == RCL_RET_OK => Error::RCL_RET_OK,
_ if e == RCL_RET_ERROR => Error::RCL_RET_ERROR,
_ if e == RCL_RET_TIMEOUT => Error::RCL_RET_TIMEOUT,
_ if e == RCL_RET_BAD_ALLOC => Error::RCL_RET_BAD_ALLOC,
_ if e == RCL_RET_INVALID_ARGUMENT => Error::RCL_RET_INVALID_ARGUMENT,
_ if e == RCL_RET_UNSUPPORTED => Error::RCL_RET_UNSUPPORTED,
_ if e == RCL_RET_ALREADY_INIT => Error::RCL_RET_ALREADY_INIT,
_ if e == RCL_RET_NOT_INIT => Error::RCL_RET_NOT_INIT,
_ if e == RCL_RET_MISMATCHED_RMW_ID => Error::RCL_RET_MISMATCHED_RMW_ID,
_ if e == RCL_RET_TOPIC_NAME_INVALID => Error::RCL_RET_TOPIC_NAME_INVALID,
_ if e == RCL_RET_SERVICE_NAME_INVALID => Error::RCL_RET_SERVICE_NAME_INVALID,
_ if e == RCL_RET_UNKNOWN_SUBSTITUTION => Error::RCL_RET_UNKNOWN_SUBSTITUTION,
_ if e == RCL_RET_ALREADY_SHUTDOWN => Error::RCL_RET_ALREADY_SHUTDOWN,
_ if e == RCL_RET_NODE_INVALID => Error::RCL_RET_NODE_INVALID,
_ if e == RCL_RET_NODE_INVALID_NAME => Error::RCL_RET_NODE_INVALID_NAME,
_ if e == RCL_RET_NODE_INVALID_NAMESPACE => Error::RCL_RET_NODE_INVALID_NAMESPACE,
_ if e == RCL_RET_PUBLISHER_INVALID => Error::RCL_RET_PUBLISHER_INVALID,
_ if e == RCL_RET_SUBSCRIPTION_INVALID => Error::RCL_RET_SUBSCRIPTION_INVALID,
_ if e == RCL_RET_SUBSCRIPTION_TAKE_FAILED => Error::RCL_RET_SUBSCRIPTION_TAKE_FAILED,
_ if e == RCL_RET_CLIENT_INVALID => Error::RCL_RET_CLIENT_INVALID,
_ if e == RCL_RET_CLIENT_TAKE_FAILED => Error::RCL_RET_CLIENT_TAKE_FAILED,
_ if e == RCL_RET_SERVICE_INVALID => Error::RCL_RET_SERVICE_INVALID,
_ if e == RCL_RET_SERVICE_TAKE_FAILED => Error::RCL_RET_SERVICE_TAKE_FAILED,
_ if e == RCL_RET_TIMER_INVALID => Error::RCL_RET_TIMER_INVALID,
_ if e == RCL_RET_TIMER_CANCELED => Error::RCL_RET_TIMER_CANCELED,
_ if e == RCL_RET_WAIT_SET_INVALID => Error::RCL_RET_WAIT_SET_INVALID,
_ if e == RCL_RET_WAIT_SET_EMPTY => Error::RCL_RET_WAIT_SET_EMPTY,
_ if e == RCL_RET_WAIT_SET_FULL => Error::RCL_RET_WAIT_SET_FULL,
_ if e == RCL_RET_INVALID_REMAP_RULE => Error::RCL_RET_INVALID_REMAP_RULE,
_ if e == RCL_RET_WRONG_LEXEME => Error::RCL_RET_WRONG_LEXEME,
_ if e == RCL_RET_INVALID_PARAM_RULE => Error::RCL_RET_INVALID_PARAM_RULE,
_ if e == RCL_RET_INVALID_LOG_LEVEL_RULE => Error::RCL_RET_INVALID_LOG_LEVEL_RULE,
_ if e == RCL_RET_EVENT_INVALID => Error::RCL_RET_EVENT_INVALID,
_ if e == RCL_RET_EVENT_TAKE_FAILED => Error::RCL_RET_EVENT_TAKE_FAILED,
_ => panic!("TODO: add error code {}", e),
}
}
}

View File

@ -1,9 +1,7 @@
include!(concat!(env!("OUT_DIR"), "/generated_msgs.rs"));
include!(concat!(env!("OUT_DIR"), "/generated_typehacks.rs"));
use msg_gen::*;
use rcl::*;
#[macro_use] extern crate failure_derive;
use serde::{Deserialize, Serialize};
use std::ffi::{CString,CStr};
use std::marker::PhantomData;
@ -11,6 +9,14 @@ use std::ops::{Deref, DerefMut};
use std::time::Duration;
use std::collections::HashMap;
use msg_gen::*;
use rcl::*;
mod error;
use error::*;
type Result<T> = std::result::Result<T, Error>;
pub trait WrappedTypesupport {
type CStruct;
@ -240,7 +246,7 @@ pub struct Context {
unsafe impl Send for Context {}
impl Context {
pub fn create() -> Result<Context, ()> {
pub fn create() -> Result<Context> {
let mut ctx: Box<rcl_context_t> = unsafe { Box::new(rcl_get_zero_initialized_context()) };
let is_valid = unsafe {
let allocator = rcutils_get_default_allocator();
@ -256,7 +262,7 @@ impl Context {
context_handle: Arc::new(Mutex::new(ctx)),
})
} else {
Err(())
Err(Error::RCL_RET_ERROR) // TODO
}
}
}
@ -286,7 +292,8 @@ pub struct Node {
}
impl Node {
pub fn create(ctx: Context, name: &str, namespace: &str) -> Result<Node, ()> {
pub fn create(ctx: Context, name: &str, namespace: &str) -> Result<Node> {
// cleanup default options.
let (res, node_handle) = {
let mut ctx_handle = ctx.context_handle.lock().unwrap();
@ -316,13 +323,13 @@ impl Node {
})
} else {
eprintln!("could not create node{}", res);
Err(())
Err(Error::from_rcl_error(res))
}
}
fn create_subscription_helper(&mut self, topic: &str, ts: *const rosidl_message_type_support_t) -> Result<rcl_subscription_t, ()> {
fn create_subscription_helper(&mut self, topic: &str, ts: *const rosidl_message_type_support_t) -> Result<rcl_subscription_t> {
let mut subscription_handle = unsafe { rcl_get_zero_initialized_subscription() };
let topic_c_string = CString::new(topic).map_err(|_| ())?;
let topic_c_string = CString::new(topic).map_err(|_|Error::RCL_RET_INVALID_ARGUMENT)?;
let result = unsafe {
let mut subscription_options = rcl_subscription_get_default_options();
@ -338,7 +345,7 @@ impl Node {
if result == RCL_RET_OK as i32 {
Ok(subscription_handle)
} else {
Err(())
Err(Error::from_rcl_error(result))
}
}
@ -346,7 +353,7 @@ impl Node {
&mut self,
topic: &str,
callback: Box<dyn FnMut(T) -> ()>,
) -> Result<&rcl_subscription_t, ()>
) -> Result<&rcl_subscription_t>
where
T: WrappedTypesupport,
{
@ -364,7 +371,7 @@ impl Node {
&mut self,
topic: &str,
callback: Box<dyn FnMut(&WrappedNativeMsg<T>) -> ()>,
) -> Result<&rcl_subscription_t, ()>
) -> Result<&rcl_subscription_t>
where
T: WrappedTypesupport,
{
@ -384,7 +391,7 @@ impl Node {
topic: &str,
topic_type: &str,
callback: Box<dyn FnMut(serde_json::Value) -> ()>,
) -> Result<&rcl_subscription_t, ()> {
) -> Result<&rcl_subscription_t> {
let ts = untyped_ts_helper(topic_type)?;
let de = untyped_deserialize_helper(topic_type)?;
let subscription_handle = self.create_subscription_helper(topic, ts)?;
@ -402,12 +409,12 @@ impl Node {
}
pub fn create_publisher<T>(&mut self, topic: &str) -> Result<Publisher<T>, ()>
pub fn create_publisher<T>(&mut self, topic: &str) -> Result<Publisher<T>>
where
T: WrappedTypesupport,
{
let mut publisher_handle = unsafe { rcl_get_zero_initialized_publisher() };
let topic_c_string = CString::new(topic).unwrap();
let topic_c_string = CString::new(topic).map_err(|_|Error::RCL_RET_INVALID_ARGUMENT)?;
let result = unsafe {
let mut publisher_options = rcl_publisher_get_default_options();
@ -429,14 +436,14 @@ impl Node {
Ok(p)
} else {
eprintln!("could not create publisher {}", result);
Err(())
Err(Error::from_rcl_error(result))
}
}
pub fn create_publisher_untyped(&mut self, topic: &str, topic_type: &str) -> Result<PublisherUntyped, ()> {
pub fn create_publisher_untyped(&mut self, topic: &str, topic_type: &str) -> Result<PublisherUntyped> {
let ts = untyped_ts_helper(topic_type)?;
let mut publisher_handle = unsafe { rcl_get_zero_initialized_publisher() };
let topic_c_string = CString::new(topic).unwrap();
let topic_c_string = CString::new(topic).map_err(|_|Error::RCL_RET_INVALID_ARGUMENT)?;
let result = unsafe {
let mut publisher_options = rcl_publisher_get_default_options();
@ -458,7 +465,7 @@ impl Node {
Ok(p)
} else {
eprintln!("could not create publisher {}", result);
Err(())
Err(Error::from_rcl_error(result))
}
}
@ -524,14 +531,14 @@ impl Node {
}
pub fn get_topic_names_and_types(&self) -> Result<HashMap<String, Vec<String>>, ()> {
pub fn get_topic_names_and_types(&self) -> Result<HashMap<String, Vec<String>>> {
let mut tnat = unsafe { rmw_get_zero_initialized_names_and_types() };
let ret = unsafe {
rcl_get_topic_names_and_types(self.node_handle.as_ref(), &mut rcutils_get_default_allocator(), false, &mut tnat)
};
if ret != RCL_RET_OK as i32 {
eprintln!("could not get topic names and types {}", ret);
return Err(());
return Err(Error::from_rcl_error(ret));
}
let names = unsafe { std::slice::from_raw_parts(tnat.names.data, tnat.names.size) };
@ -589,12 +596,12 @@ impl<T> Publisher<T>
where
T: WrappedTypesupport,
{
pub fn publish(&self, msg: &T) -> Result<(), ()>
pub fn publish(&self, msg: &T) -> Result<()>
where
T: WrappedTypesupport,
{
// upgrade to actual ref. if still alive
let publisher = self.handle.upgrade().ok_or(())?;
let publisher = self.handle.upgrade().ok_or(Error::RCL_RET_PUBLISHER_INVALID)?;
// copy rust msg to native and publish it
let native_msg: WrappedNativeMsg<T> = WrappedNativeMsg::<T>::from(msg);
let result = unsafe {
@ -609,16 +616,16 @@ where
Ok(())
} else {
eprintln!("coult not publish {}", result);
Err(())
Err(Error::from_rcl_error(result))
}
}
pub fn publish_native(&self, msg: &WrappedNativeMsg<T>) -> Result<(), ()>
pub fn publish_native(&self, msg: &WrappedNativeMsg<T>) -> Result<()>
where
T: WrappedTypesupport,
{
// upgrade to actual ref. if still alive
let publisher = self.handle.upgrade().ok_or(())?;
let publisher = self.handle.upgrade().ok_or(Error::RCL_RET_PUBLISHER_INVALID)?;
let result =
unsafe { rcl_publish(publisher.as_ref(), msg.void_ptr(), std::ptr::null_mut()) };
@ -626,22 +633,22 @@ where
Ok(())
} else {
eprintln!("could not publish native {}", result);
Err(())
Err(Error::from_rcl_error(result))
}
}
}
impl PublisherUntyped {
pub fn publish(&self, msg: serde_json::Value) -> Result<(), ()> {
pub fn publish(&self, msg: serde_json::Value) -> Result<()> {
// upgrade to actual ref. if still alive
let publisher = self.handle.upgrade().ok_or(())?;
let publisher = self.handle.upgrade().ok_or(Error::RCL_RET_PUBLISHER_INVALID)?;
// figure out which serializer to use, publish, then destroy
let se = untyped_serialize_helper(&self.type_)?;
let dealloc = untyped_dealloc_helper(&self.type_)?;
// copy rust msg to native and publish it
let native_ptr = se(msg)?;
let native_ptr = se(msg).map_err(|e| Error::SerdeError { err: e.to_string() })?;
let result = unsafe {
rcl_publish(
publisher.as_ref(),
@ -656,7 +663,7 @@ impl PublisherUntyped {
Ok(())
} else {
eprintln!("coult not publish {}", result);
Err(())
Err(Error::from_rcl_error(result))
}
}
}

View File

@ -1,11 +1,12 @@
use std::thread;
use std::time::Duration;
use failure::Error;
use r2r::*;
#[test]
// Let's create and drop a lot of node and publishers for a while to see that we can cope.
fn doesnt_crash() -> Result<(), ()> {
fn doesnt_crash() -> Result<(), Error> {
// a global shared context.
let ctx = Context::create()?;
@ -29,7 +30,7 @@ fn doesnt_crash() -> Result<(), ()> {
// move publisher to its own thread and publish as fast as we can
thread::spawn(move || loop {
let res = p.publish(&to_send);
thread::sleep(std::time::Duration::from_millis(1));
thread::sleep(Duration::from_millis(1));
match res {
Ok(_) => (),
Err(_) => {
@ -42,7 +43,7 @@ fn doesnt_crash() -> Result<(), ()> {
// spin to simulate some load
for _j in 0..100 {
node.spin_once(std::time::Duration::from_millis(10));
node.spin_once(Duration::from_millis(10));
}
// println!("all done {}-{}", c, i);