1use std::{
2 ffi::{c_char, CStr, CString},
3 marker::PhantomData,
4 ptr::NonNull,
5};
6
7use webui_sys::*;
8
9use crate::{EventType, WebUIError, Window, CONTEXT};
10
11#[repr(transparent)]
13pub struct Event<'a> {
14 pub(crate) inner: NonNull<webui_event_t>,
15 _marker: PhantomData<&'a webui_event_t>,
16}
17
18impl<'a> Event<'a> {
19 pub(crate) unsafe fn new(ptr: *mut webui_event_t) -> Option<Self> {
20 NonNull::new(ptr).map(|inner| Self {
21 inner,
22 _marker: std::marker::PhantomData,
23 })
24 }
25
26 pub(crate) fn get_event(&self) -> &webui_event_t {
28 unsafe { self.inner.as_ref() }
29 }
30
31 pub(crate) fn as_ptr(&self) -> *mut webui_event_t {
33 self.inner.as_ptr()
34 }
35
36 pub fn window(&self) -> Option<Window> {
38 let window = self.get_event().window;
39 CONTEXT
40 .lock()
41 .unwrap()
42 .get(&window)
43 .and_then(|x| x.upgrade())
44 .map(|inner| Window { inner })
45 }
46
47 pub(crate) fn bind_id(&self) -> usize {
48 self.get_event().bind_id
49 }
50
51 pub fn event_type(&self) -> EventType {
53 unsafe { std::mem::transmute(self.get_event().event_type) }
54 }
55
56 pub fn element(&self) -> String {
58 let element = self.get_event().element;
59 unsafe { CStr::from_ptr(element).to_string_lossy().to_string() }
60 }
61
62 pub fn event_number(&self) -> usize {
64 self.get_event().event_number
65 }
66
67 pub fn client_id(&self) -> usize {
69 self.get_event().client_id
70 }
71
72 pub fn connection_id(&self) -> usize {
74 self.get_event().connection_id
75 }
76
77 pub fn cookies(&self) -> Option<String> {
79 let cookies = self.get_event().cookies;
80 (!cookies.is_null()).then_some(unsafe { CStr::from_ptr(cookies).to_string_lossy().to_string() })
81 }
82
83 pub fn show_client(&self, content: &str) -> Result<(), WebUIError> {
86 let content = CString::new(content).unwrap();
87 let result = unsafe { webui_show_client(self.as_ptr(), content.as_ptr()) };
88 WebUIError::from_bool(result)
89 }
90
91 pub fn close_client(&self) {
93 unsafe { webui_close_client(self.as_ptr()) }
94 }
95
96 pub fn navigate_client(&self, url: &str) {
98 let url = CString::new(url).unwrap();
99 unsafe { webui_navigate_client(self.as_ptr(), url.as_ptr()) }
100 }
101
102 pub fn run_client(&self, script: &str) {
104 let script = CString::new(script).unwrap();
105 unsafe {
106 webui_run_client(self.as_ptr(), script.as_ptr());
107 }
108 }
109
110 pub fn script_client(&self, script: &str, timeout: usize, capacity: usize) -> Result<String, WebUIError> {
112 let mut buffer: Vec<c_char> = Vec::with_capacity(capacity);
113 let script = CString::new(script).unwrap();
114 unsafe { webui_script_client(self.as_ptr(), script.as_ptr(), timeout, buffer.as_mut_ptr(), capacity) }
115 .then(|| unsafe { CStr::from_ptr(buffer.as_ptr()) }.to_string_lossy().to_string())
116 .ok_or(WebUIError::get_last_error())
117 }
118
119 pub fn get_count(&self) -> usize {
121 unsafe { webui_get_count(self.as_ptr()) }
122 }
123
124 pub fn get_int(&self) -> i64 {
126 unsafe { webui_get_int(self.as_ptr()) }
127 }
128
129 pub fn get_int_at(&self, index: usize) -> i64 {
131 unsafe { webui_get_int_at(self.as_ptr(), index) }
132 }
133
134 pub fn get_float(&self) -> f64 {
136 unsafe { webui_get_float(self.as_ptr()) }
137 }
138
139 pub fn get_float_at(&self, index: usize) -> f64 {
141 unsafe { webui_get_float_at(self.as_ptr(), index) }
142 }
143
144 pub fn get_string(&self) -> String {
146 unsafe {
147 let ptr = webui_get_string(self.as_ptr());
148 CStr::from_ptr(ptr).to_string_lossy().to_string()
149 }
150 }
151
152 pub fn get_string_at(&self, index: usize) -> String {
154 unsafe {
155 let ptr = webui_get_string_at(self.as_ptr(), index);
156 CStr::from_ptr(ptr).to_string_lossy().to_string()
157 }
158 }
159
160 pub fn get_bool(&self) -> bool {
162 unsafe { webui_get_bool(self.as_ptr()) }
163 }
164
165 pub fn get_bool_at(&self, index: usize) -> bool {
167 unsafe { webui_get_bool_at(self.as_ptr(), index) }
168 }
169
170 pub fn get_size(&self) -> usize {
172 unsafe { webui_get_size(self.as_ptr()) }
173 }
174
175 pub fn get_size_at(&self, index: usize) -> usize {
177 unsafe { webui_get_size_at(self.as_ptr(), index) }
178 }
179
180 pub fn return_int(&self, value: i64) {
182 unsafe { webui_return_int(self.as_ptr(), value) }
183 }
184
185 pub fn return_float(&self, value: f64) {
187 unsafe { webui_return_float(self.as_ptr(), value) }
188 }
189
190 pub fn return_string<S: AsRef<str>>(&self, value: S) {
192 let c_str = std::ffi::CString::new(value.as_ref()).unwrap_or_default();
193 unsafe { webui_return_string(self.as_ptr(), c_str.as_ptr()) }
194 }
195
196 pub fn return_bool(&self, value: bool) {
198 unsafe { webui_return_bool(self.as_ptr(), value) }
199 }
200
201 pub fn send_raw<T>(&self, function: &str, data: T)
203 where
204 T: Into<Vec<u8>>,
205 {
206 let function = CString::new(function).unwrap();
207 let data = data.into().into_boxed_slice();
208 unsafe { webui_send_raw_client(self.as_ptr(), function.as_ptr(), data.as_ptr() as _, data.len()) }
209 }
210}