1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#![macro_use]
use libc::{ c_char, c_void };
use std::ffi::{ CString, CStr };
use std::slice;
use std::fmt;
use std::error;
#[derive(Debug)]
pub enum APIError {
GenericError
}
impl fmt::Display for APIError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "{}", error::Error::description(self))
}
}
impl error::Error for APIError {
fn description(&self) -> &str {
match *self {
APIError::GenericError => "Generic OpenZWave API Error"
}
}
}
pub fn res_to_result(res: bool) -> Result<(), APIError> {
if res { Ok(()) } else { Err(APIError::GenericError) }
}
pub type RustStringCreator = extern fn(*const c_char) -> *mut c_char;
pub type RustVecCreator<T> = extern fn(*const T, usize) -> *mut c_void;
pub extern "C" fn rust_string_creator(data: *const c_char) -> *mut c_char {
let c_str = unsafe { CStr::from_ptr(data) };
let lossy_str = c_str.to_string_lossy();
let own_str = lossy_str.into_owned();
return CString::new(own_str).unwrap().into_raw();
}
pub fn recover_string(data: *mut c_char) -> String {
unsafe {
CString::from_raw(data)
} .into_string().unwrap()
}
pub fn recover_vec<T>(data: *mut Vec<T>) -> Box<Vec<T>> {
unsafe { Box::from_raw(data) }
}
pub extern "C" fn rust_vec_creator<T: Clone>(data: *const T, length: usize) -> *mut c_void {
let rust_data = unsafe { slice::from_raw_parts(data, length) };
let mut vec: Box<Vec<T>> = Box::new(Vec::with_capacity(length));
vec.extend_from_slice(rust_data);
Box::into_raw(vec) as *mut c_void
}
pub extern "C" fn rust_string_vec_creator(data: *const *const c_char, length: usize) -> *mut c_void {
let rust_data = unsafe { slice::from_raw_parts(data, length) };
let mut vec: Box<Vec<String>> = Box::new(Vec::with_capacity(length));
for item in rust_data {
let c_str = unsafe { CStr::from_ptr(*item) };
let lossy_str = c_str.to_string_lossy();
let own_str = lossy_str.into_owned();
vec.push(own_str);
}
Box::into_raw(vec) as *mut c_void
}
#[macro_export]
macro_rules! c_like_enum {
( $name: ident { $($variant: ident = $value: expr),+ } ) => {
#[derive(Debug, Clone, Copy)]
pub enum $name {
$($variant = $value,)+
}
impl $name {
pub fn from_u8(value: u8) -> Option<$name> {
match value {
$($value => Some($name::$variant),)+
_ => None
}
}
}
}
}