falco_plugin/plugin/exported_tables/field/
readonly.rs

1use crate::internals::tables::export::DynamicFieldValue;
2use crate::plugin::exported_tables::field_value::traits::FieldValue;
3use crate::plugin::exported_tables::field_value::traits::{seal, StaticField};
4use crate::plugin::exported_tables::metadata::HasMetadata;
5use crate::plugin::tables::data::FieldTypeId;
6use anyhow::Error;
7use falco_plugin_api::ss_plugin_state_data;
8use std::ffi::CStr;
9use std::ops::{Deref, DerefMut};
10
11/// Export the field via Falco tables API with read-only access
12///
13/// This is a wrapper that tells the Rust SDK to export a field to other plugins,
14/// but only with read access. Please note that this does not limit write access
15/// from within your plugin (bypassing the table API).
16///
17/// This type implements [`Deref`] and [`DerefMut`], so you do not need any extra
18/// code when accessing the actual data.
19#[derive(Debug)]
20pub struct Readonly<T>(T);
21
22impl<T: FieldValue + Default> HasMetadata for Readonly<T> {
23    type Metadata = ();
24
25    fn new_with_metadata(_tag: &'static CStr, _meta: &Self::Metadata) -> Result<Self, Error> {
26        Ok(Self(T::default()))
27    }
28}
29
30impl<T> Deref for Readonly<T> {
31    type Target = T;
32
33    fn deref(&self) -> &Self::Target {
34        &self.0
35    }
36}
37
38impl<T> DerefMut for Readonly<T> {
39    fn deref_mut(&mut self) -> &mut Self::Target {
40        &mut self.0
41    }
42}
43
44impl<T: FieldValue> seal::Sealed for Readonly<T> {}
45
46impl<T: FieldValue> FieldValue for Readonly<T> {
47    fn to_data(&self, out: &mut ss_plugin_state_data, type_id: FieldTypeId) -> Result<(), Error> {
48        self.0.to_data(out, type_id)
49    }
50}
51
52impl<T: StaticField> StaticField for Readonly<T> {
53    const TYPE_ID: FieldTypeId = T::TYPE_ID;
54    const READONLY: bool = true;
55}
56
57impl<T: TryFrom<DynamicFieldValue>> TryFrom<DynamicFieldValue> for Readonly<T> {
58    type Error = T::Error;
59
60    fn try_from(value: DynamicFieldValue) -> Result<Self, Self::Error> {
61        Ok(Self(T::try_from(value)?))
62    }
63}