falco_plugin/tables/vtable/
writer.rs1use crate::error::last_error::LastError;
2use crate::tables::vtable::TableError;
3use crate::tables::vtable::TableError::BadVtable;
4use falco_plugin_api::{
5 ss_plugin_rc, ss_plugin_state_data, ss_plugin_table_entry_t, ss_plugin_table_field_t,
6 ss_plugin_table_t, ss_plugin_table_writer_vtable_ext,
7};
8use std::marker::PhantomData;
9
10pub trait TableWriter: private::TableWriterImpl {}
15
16impl<T: private::TableWriterImpl> TableWriter for T {}
17
18pub(crate) mod private {
19 use super::*;
20
21 pub trait TableWriterImpl {
22 type Error: std::error::Error + Send + Sync + 'static;
23
24 unsafe fn clear_table(
25 &self,
26 t: *mut ss_plugin_table_t,
27 ) -> Result<ss_plugin_rc, Self::Error>;
28
29 unsafe fn erase_table_entry(
30 &self,
31 t: *mut ss_plugin_table_t,
32 key: *const ss_plugin_state_data,
33 ) -> Result<ss_plugin_rc, Self::Error>;
34
35 unsafe fn create_table_entry(
36 &self,
37 t: *mut ss_plugin_table_t,
38 ) -> Result<*mut ss_plugin_table_entry_t, Self::Error>;
39
40 unsafe fn destroy_table_entry(
41 &self,
42 t: *mut ss_plugin_table_t,
43 e: *mut ss_plugin_table_entry_t,
44 );
45
46 fn destroy_table_entry_fn(
47 &self,
48 ) -> Option<unsafe extern "C" fn(t: *mut ss_plugin_table_t, e: *mut ss_plugin_table_entry_t)>;
49
50 unsafe fn add_table_entry(
51 &self,
52 t: *mut ss_plugin_table_t,
53 key: *const ss_plugin_state_data,
54 entry: *mut ss_plugin_table_entry_t,
55 ) -> Result<*mut ss_plugin_table_entry_t, Self::Error>;
56
57 unsafe fn write_entry_field(
58 &self,
59 t: *mut ss_plugin_table_t,
60 e: *mut ss_plugin_table_entry_t,
61 f: *const ss_plugin_table_field_t,
62 in_: *const ss_plugin_state_data,
63 ) -> Result<ss_plugin_rc, Self::Error>;
64
65 fn last_error(&self) -> &LastError;
66 }
67}
68
69#[derive(Debug)]
74pub struct LazyTableWriter<'t> {
75 writer_ext: &'t ss_plugin_table_writer_vtable_ext,
76 pub(crate) last_error: LastError,
77}
78
79impl<'t> LazyTableWriter<'t> {
80 pub(crate) fn try_from(
81 writer_ext: &'t ss_plugin_table_writer_vtable_ext,
82 last_error: LastError,
83 ) -> Result<Self, TableError> {
84 Ok(LazyTableWriter {
85 writer_ext,
86 last_error,
87 })
88 }
89
90 pub fn validate(&self) -> Result<ValidatedTableWriter<'_>, TableError> {
97 Ok(ValidatedTableWriter {
98 clear_table: self
99 .writer_ext
100 .clear_table
101 .ok_or(BadVtable("clear_table"))?,
102 erase_table_entry: self
103 .writer_ext
104 .erase_table_entry
105 .ok_or(BadVtable("erase_table_entry"))?,
106 create_table_entry: self
107 .writer_ext
108 .create_table_entry
109 .ok_or(BadVtable("create_table_entry"))?,
110 destroy_table_entry: self
111 .writer_ext
112 .destroy_table_entry
113 .ok_or(BadVtable("destroy_table_entry"))?,
114 add_table_entry: self
115 .writer_ext
116 .add_table_entry
117 .ok_or(BadVtable("add_table_entry"))?,
118 write_entry_field: self
119 .writer_ext
120 .write_entry_field
121 .ok_or(BadVtable("write_entry_field"))?,
122 last_error: self.last_error.clone(),
123 lifetime: PhantomData,
124 })
125 }
126}
127
128impl private::TableWriterImpl for LazyTableWriter<'_> {
129 type Error = TableError;
130
131 unsafe fn clear_table(&self, t: *mut ss_plugin_table_t) -> Result<ss_plugin_rc, TableError> {
132 unsafe {
133 Ok(self
134 .writer_ext
135 .clear_table
136 .ok_or(BadVtable("clear_table"))?(t))
137 }
138 }
139
140 unsafe fn erase_table_entry(
141 &self,
142 t: *mut ss_plugin_table_t,
143 key: *const ss_plugin_state_data,
144 ) -> Result<ss_plugin_rc, TableError> {
145 unsafe {
146 Ok(self
147 .writer_ext
148 .erase_table_entry
149 .ok_or(BadVtable("erase_table_entry"))?(
150 t, key
151 ))
152 }
153 }
154
155 unsafe fn create_table_entry(
156 &self,
157 t: *mut ss_plugin_table_t,
158 ) -> Result<*mut ss_plugin_table_entry_t, TableError> {
159 unsafe {
160 Ok(self
161 .writer_ext
162 .create_table_entry
163 .ok_or(BadVtable("create_table_entry"))?(t))
164 }
165 }
166
167 unsafe fn destroy_table_entry(
168 &self,
169 t: *mut ss_plugin_table_t,
170 e: *mut ss_plugin_table_entry_t,
171 ) {
172 let Some(destroy_table_entry) = self.writer_ext.destroy_table_entry else {
173 return;
174 };
175
176 unsafe { destroy_table_entry(t, e) }
177 }
178
179 fn destroy_table_entry_fn(
180 &self,
181 ) -> Option<unsafe extern "C" fn(t: *mut ss_plugin_table_t, e: *mut ss_plugin_table_entry_t)>
182 {
183 self.writer_ext.destroy_table_entry
184 }
185
186 unsafe fn add_table_entry(
187 &self,
188 t: *mut ss_plugin_table_t,
189 key: *const ss_plugin_state_data,
190 entry: *mut ss_plugin_table_entry_t,
191 ) -> Result<*mut ss_plugin_table_entry_t, TableError> {
192 unsafe {
193 Ok(self
194 .writer_ext
195 .add_table_entry
196 .ok_or(BadVtable("add_table_entry"))?(
197 t, key, entry
198 ))
199 }
200 }
201
202 unsafe fn write_entry_field(
203 &self,
204 t: *mut ss_plugin_table_t,
205 e: *mut ss_plugin_table_entry_t,
206 f: *const ss_plugin_table_field_t,
207 in_: *const ss_plugin_state_data,
208 ) -> Result<ss_plugin_rc, TableError> {
209 unsafe {
210 Ok(self
211 .writer_ext
212 .write_entry_field
213 .ok_or(BadVtable("write_entry_field"))?(
214 t, e, f, in_
215 ))
216 }
217 }
218
219 fn last_error(&self) -> &LastError {
220 &self.last_error
221 }
222}
223
224#[derive(Debug)]
228pub struct ValidatedTableWriter<'t> {
229 clear_table: unsafe extern "C" fn(t: *mut ss_plugin_table_t) -> ss_plugin_rc,
230 erase_table_entry: unsafe extern "C" fn(
231 t: *mut ss_plugin_table_t,
232 key: *const ss_plugin_state_data,
233 ) -> ss_plugin_rc,
234 create_table_entry:
235 unsafe extern "C" fn(t: *mut ss_plugin_table_t) -> *mut ss_plugin_table_entry_t,
236 destroy_table_entry:
237 unsafe extern "C" fn(t: *mut ss_plugin_table_t, e: *mut ss_plugin_table_entry_t),
238 add_table_entry: unsafe extern "C" fn(
239 t: *mut ss_plugin_table_t,
240 key: *const ss_plugin_state_data,
241 entry: *mut ss_plugin_table_entry_t,
242 ) -> *mut ss_plugin_table_entry_t,
243 write_entry_field: unsafe extern "C" fn(
244 t: *mut ss_plugin_table_t,
245 e: *mut ss_plugin_table_entry_t,
246 f: *const ss_plugin_table_field_t,
247 in_: *const ss_plugin_state_data,
248 ) -> ss_plugin_rc,
249
250 pub(crate) last_error: LastError,
251 lifetime: PhantomData<&'t ()>,
252}
253
254impl private::TableWriterImpl for ValidatedTableWriter<'_> {
255 type Error = std::convert::Infallible;
256
257 unsafe fn clear_table(&self, t: *mut ss_plugin_table_t) -> Result<ss_plugin_rc, Self::Error> {
258 unsafe { Ok((self.clear_table)(t)) }
259 }
260
261 unsafe fn erase_table_entry(
262 &self,
263 t: *mut ss_plugin_table_t,
264 key: *const ss_plugin_state_data,
265 ) -> Result<ss_plugin_rc, Self::Error> {
266 unsafe { Ok((self.erase_table_entry)(t, key)) }
267 }
268
269 unsafe fn create_table_entry(
270 &self,
271 t: *mut ss_plugin_table_t,
272 ) -> Result<*mut ss_plugin_table_entry_t, Self::Error> {
273 unsafe { Ok((self.create_table_entry)(t)) }
274 }
275
276 unsafe fn destroy_table_entry(
277 &self,
278 t: *mut ss_plugin_table_t,
279 e: *mut ss_plugin_table_entry_t,
280 ) {
281 unsafe { (self.destroy_table_entry)(t, e) }
282 }
283
284 fn destroy_table_entry_fn(
285 &self,
286 ) -> Option<unsafe extern "C" fn(t: *mut ss_plugin_table_t, e: *mut ss_plugin_table_entry_t)>
287 {
288 Some(self.destroy_table_entry)
289 }
290
291 unsafe fn add_table_entry(
292 &self,
293 t: *mut ss_plugin_table_t,
294 key: *const ss_plugin_state_data,
295 entry: *mut ss_plugin_table_entry_t,
296 ) -> Result<*mut ss_plugin_table_entry_t, Self::Error> {
297 unsafe { Ok((self.add_table_entry)(t, key, entry)) }
298 }
299
300 unsafe fn write_entry_field(
301 &self,
302 t: *mut ss_plugin_table_t,
303 e: *mut ss_plugin_table_entry_t,
304 f: *const ss_plugin_table_field_t,
305 in_: *const ss_plugin_state_data,
306 ) -> Result<ss_plugin_rc, Self::Error> {
307 unsafe { Ok((self.write_entry_field)(t, e, f, in_)) }
308 }
309
310 fn last_error(&self) -> &LastError {
311 &self.last_error
312 }
313}