websocket_std/ffi/
common.rs1use super::super::sync::client::{WSEvent as RWSEvent, Reason};
2use std::ffi::{c_void, CString};
3use crate::result::WebSocketError;
4use std::ptr;
5
6#[repr(C)]
7#[allow(non_camel_case_types)]
8enum WSEvent {
9 ON_CONNECT,
10 ON_TEXT,
11 ON_CLOSE
12}
13
14#[repr(C)]
15#[allow(non_camel_case_types)]
16pub struct WSEvent_t {
17 event: WSEvent,
18 value: *const c_void
19}
20
21#[repr(C)]
22#[allow(non_camel_case_types)]
23enum WSReason {
24 SERVER_CLOSED,
25 CLIENT_CLOSED
26}
27
28#[repr(C)]
29#[allow(non_camel_case_types)]
30struct WSReason_t {
31 reason: WSReason,
32 status: u16
33}
34
35#[repr(C)]
36#[derive(Debug, Clone)]
37pub enum WSStatus {
38 OK,
39 UnreachableHost,
40 HandShake,
41 InvalidFrame,
42 ConnectionClose,
43 DecodingFromUTF8,
44 IOError,
45}
46
47pub fn rust_error_to_c_error(error: WebSocketError) -> WSStatus {
48 match error {
49 WebSocketError::UnreachableHost => WSStatus::UnreachableHost,
50 WebSocketError::HandShake => WSStatus::HandShake,
51 WebSocketError::InvalidFrame => WSStatus::InvalidFrame,
52 WebSocketError::ConnectionClose => WSStatus::ConnectionClose,
53 WebSocketError::DecodingFromUTF8 => WSStatus::DecodingFromUTF8,
54 WebSocketError::IOError => WSStatus::IOError
55 }
56}
57
58#[no_mangle]
59pub extern "C" fn from_rust_event(event: &RWSEvent) -> WSEvent_t {
60 match event {
61 RWSEvent::ON_CONNECT(msg) => {
62 let mut value = ptr::null_mut();
63 if let Some(m) = msg {
64 println!("[RUST] M: {}", m);
65 let m = m.replace('\0', "");
66 let m = m.trim();
67 let c_str = CString::new(m).map_err(|err| {
68 eprintln!("Error converting to CString: {err}");
69 }).unwrap();
70 value = c_str.into_raw();
71 }
72 WSEvent_t { event: WSEvent::ON_CONNECT, value: value as *const c_void }
73 }
74 ,
75 RWSEvent::ON_TEXT(msg) => {
76 let c_str = CString::new(msg.clone()).unwrap();
77 WSEvent_t { event: WSEvent::ON_TEXT, value: c_str.into_raw() as *const c_void }
78 },
79 RWSEvent::ON_CLOSE(reason) => {
80 let (reason, status) = match reason {
81 Reason::SERVER_CLOSE(status) => (WSReason::SERVER_CLOSED, status.clone()),
82 Reason::CLIENT_CLOSE(status) => (WSReason::CLIENT_CLOSED, status.clone())
83 };
84 let reason = WSReason_t { reason, status };
85 let reason = Box::into_raw(Box::new(reason));
86 WSEvent_t { event: WSEvent::ON_CLOSE, value: reason as *const c_void }
87 }
88 }
89}