falco_plugin/plugin/tables/entry/
mod.rs

1use crate::plugin::error::as_result::{AsResult, WithLastError};
2use crate::plugin::tables::data::Value;
3use crate::plugin::tables::field::Field;
4use crate::plugin::tables::traits::{EntryWrite, TableMetadata};
5use crate::plugin::tables::vtable::reader::TableReader;
6use crate::plugin::tables::vtable::writer::TableWriter;
7use falco_plugin_api::ss_plugin_table_t;
8
9pub(in crate::plugin::tables) mod raw;
10use raw::RawEntry;
11
12/// # An entry in a Falco plugin table
13///
14/// This type wraps an opaque pointer representing an entry in a table and allows individual
15/// field access (given a [`Field`] reference).
16///
17/// You can add methods to this type using the `#[derive(TableMetadata)]` macro.
18/// See the [module documentation](`crate::tables::import`) for details.
19#[derive(Debug)]
20pub struct Entry<M> {
21    pub(in crate::plugin::tables) raw_entry: RawEntry,
22    pub(in crate::plugin::tables) table: *mut ss_plugin_table_t,
23    pub(in crate::plugin::tables) metadata: M,
24}
25
26impl<M: TableMetadata + Clone> crate::plugin::tables::traits::Entry for Entry<M> {
27    type Metadata = M;
28
29    fn new(raw_entry: RawEntry, table: *mut ss_plugin_table_t, metadata: Self::Metadata) -> Self {
30        Self {
31            raw_entry,
32            table,
33            metadata,
34        }
35    }
36
37    fn get_metadata(&self) -> &Self::Metadata {
38        &self.metadata
39    }
40
41    fn into_raw(self) -> RawEntry {
42        self.raw_entry
43    }
44}
45
46impl<M> Entry<M> {
47    /// Get a field value for this entry
48    pub fn read_field<V: Value + ?Sized>(
49        &self,
50        reader: &impl TableReader,
51        field: &Field<V, Entry<M>>,
52    ) -> Result<V::Value<'_>, anyhow::Error> {
53        field.validator.check(self.table)?;
54        unsafe {
55            self.raw_entry
56                .read_field_with_assoc::<V>(reader, field.field.field, &field.field.assoc_data)
57                .ok_or_else(|| anyhow::anyhow!("Could not read field value"))
58                .with_last_error(reader.last_error())
59        }
60    }
61
62    /// Set a field value for this entry
63    pub fn write_field<V: Value<AssocData = ()> + ?Sized>(
64        &self,
65        writer: &impl TableWriter,
66        field: &Field<V, Entry<M>>,
67        val: &V,
68    ) -> Result<(), anyhow::Error> {
69        field.validator.check(self.table)?;
70        unsafe {
71            self.raw_entry
72                .write_field(writer, field.field.field, &val.to_data())
73                .as_result()
74                .with_last_error(writer.last_error())
75        }
76    }
77}
78
79impl<M, V: Value<AssocData = ()> + ?Sized> EntryWrite<&Field<V, Entry<M>>, V> for Entry<M> {
80    fn write_field(
81        &self,
82        writer: &impl TableWriter,
83        field: &Field<V, Entry<M>>,
84        val: &V,
85    ) -> Result<(), anyhow::Error> {
86        Entry::write_field(self, writer, field, val)
87    }
88}