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