websocket_std/ffi/
common.rs

1use 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}