rust_lirc_client_sys/
lib.rs1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4
5use std::{
6 ffi::{CStr, CString},
7 mem::MaybeUninit,
8};
9
10include!("./bindings.rs");
11
12pub fn readconfig(path: Option<String>) -> Result<lirc_config, std::io::Error> {
13 let c_path = path.map(|p| CString::new(p).unwrap());
14 let c_str = match c_path {
15 Some(p) => p.as_ptr(),
16 None => std::ptr::null(),
17 };
18
19 unsafe {
20 let mut raw = MaybeUninit::uninit();
21 let ret = lirc_readconfig(c_str, raw.as_mut_ptr(), None);
22
23 if ret != 0 {
24 return Err(std::io::Error::last_os_error());
25 }
26
27 Ok(std::ptr::read(raw.assume_init()))
28 }
29}
30
31pub fn readconfig_only(path: Option<&str>) -> Result<lirc_config, i32> {
32 let c_path = path.map(|p| CString::new(p).unwrap());
33 let c_str = match c_path {
34 Some(p) => p.as_ptr(),
35 None => std::ptr::null(),
36 };
37
38 unsafe {
39 let mut raw = MaybeUninit::uninit();
40
41 let ret = lirc_readconfig_only(c_str, raw.as_mut_ptr(), None);
42 if ret == -1 {
43 return Err(-ret);
44 }
45
46 Ok(std::ptr::read(raw.assume_init()))
47 }
48}
49
50pub fn freeconfig(mut conf: lirc_config) {
51 unsafe {
52 lirc_freeconfig(&mut conf);
53 }
54}
55
56pub fn init(prog: &str, verbose: u32) -> Result<i32, std::io::Error> {
57 unsafe {
58 let prog_str = CString::new(prog).unwrap();
59 let ret = lirc_init(prog_str.as_ptr(), verbose);
60 if ret < 0 {
61 return Err(std::io::Error::last_os_error());
62 }
63
64 Ok(ret)
65 }
66}
67
68pub fn deinit() -> Result<(), std::io::Error> {
69 unsafe {
70 let ret = lirc_deinit();
71 if ret < 0 {
72 return Err(std::io::Error::last_os_error());
73 }
74
75 Ok(())
76 }
77}
78
79pub fn send_one(fd: i32, remote: &str, key: &str) -> Result<(), i32> {
80 let r = std::ffi::CString::new(remote).unwrap();
81 let k = std::ffi::CString::new(key).unwrap();
82
83 unsafe {
84 let ret = lirc_send_one(fd, r.as_ptr(), k.as_ptr());
85 if ret != 0 {
86 return Err(ret);
87 }
88
89 Ok(())
90 }
91}
92
93pub fn nextcode() -> Result<String, i32> {
94 unsafe {
95 let mut str_buf = MaybeUninit::uninit();
96 let ret = lirc_nextcode(str_buf.as_mut_ptr());
97 if ret != 0 {
98 return Err(ret);
99 }
100
101 let r = std::ffi::CStr::from_ptr(str_buf.assume_init()).to_str();
102 Ok(String::from(r.unwrap()))
103 }
104}
105
106pub fn code2char(mut conf: lirc_config, code: &mut str) -> Result<String, i32> {
107 unsafe {
108 let mut c = MaybeUninit::uninit();
109 let ret = lirc_code2char(&mut conf, code.as_mut_ptr(), c.as_mut_ptr());
110 if ret != 0 {
111 return Err(ret);
112 }
113
114 let a = std::ffi::CStr::from_ptr(c.assume_init() as *mut ::std::os::raw::c_char).to_str();
115 Ok(String::from(a.unwrap()))
116 }
117}
118
119pub fn get_local_socket(path: &str, quiet: bool) -> Result<i32, std::io::Error> {
120 let q = if quiet { 1 } else { 0 };
121 let p = std::ffi::CString::new(path).unwrap();
122
123 unsafe {
124 let r = lirc_get_local_socket(p.as_ptr(), q);
125 if r < 0 {
126 return Err(std::io::Error::last_os_error());
127 }
128
129 Ok(r)
130 }
131}
132
133pub fn get_remote_socket(host: &str, port: i32, quiet: bool) -> Result<i32, i32> {
134 unsafe {
135 let q: i32 = if quiet { 1 } else { 0 };
136 let h = std::ffi::CString::new(host).unwrap();
137 let r = lirc_get_remote_socket(h.as_ptr(), port, q);
138 if r < 0 {
139 return Err(r);
140 }
141
142 Ok(r)
143 }
144}
145
146pub fn set_mode(conf: &mut lirc_config, mode: &str) -> Result<String, std::io::Error> {
147 unsafe {
148 let m = std::ffi::CString::new(mode).expect("Failed to convert mode");
149
150 let ret = lirc_setmode(conf, m.as_ptr());
151 let ret_mode = CStr::from_ptr(ret);
152
153 if ret_mode.to_str().unwrap().eq(mode) {
154 return Err(std::io::Error::last_os_error());
155 }
156
157 Ok(ret_mode.to_str().unwrap().to_string())
158 }
159}
160
161#[cfg(test)]
162mod tests {
163 use super::*;
164
165 #[test]
166 fn test_init_deinit() {
167 let ret = init("Test", 1);
168 assert!(ret.is_ok(), "{:?}", ret.err());
169 assert!(ret.unwrap() > 0);
170
171 let ret = deinit();
172 assert!(ret.is_ok(), "{:?}", ret.err());
173
174 let ret = init("Test1", 10);
175 assert!(ret.is_ok(), "{:?}", ret.err());
176 assert!(ret.unwrap() > 0);
177
178 let ret = deinit();
179 assert!(ret.is_ok(), "{:?}", ret.err());
180 }
181}