falco_plugin/plugin/exported_tables/
macros.rs

1#[doc(hidden)]
2#[macro_export]
3macro_rules! table_export_expose_internals {
4    () => {
5        pub mod export {
6            pub use $crate::plugin::exported_tables::entry::table_metadata::traits::TableMetadata;
7            pub use $crate::plugin::exported_tables::entry::traits::Entry;
8            pub use $crate::plugin::exported_tables::field_descriptor::FieldDescriptor;
9            pub use $crate::plugin::exported_tables::field_descriptor::FieldId;
10            pub use $crate::plugin::exported_tables::field_descriptor::FieldRef;
11            pub use $crate::plugin::exported_tables::field_value::dynamic::DynamicFieldValue;
12            pub use $crate::plugin::exported_tables::metadata::HasMetadata;
13            pub use $crate::plugin::exported_tables::metadata::Metadata;
14            pub use $crate::plugin::exported_tables::ref_shared::RefShared;
15
16            pub use $crate::plugin::exported_tables::static_field_specialization::StaticFieldCheck;
17            pub use $crate::plugin::exported_tables::static_field_specialization::StaticFieldFallback;
18            pub use $crate::plugin::exported_tables::static_field_specialization::StaticFieldGet;
19            pub use $crate::plugin::exported_tables::static_field_specialization::StaticFieldGetFallback;
20            pub use $crate::plugin::exported_tables::static_field_specialization::StaticFieldSet;
21            pub use $crate::plugin::exported_tables::static_field_specialization::StaticFieldSetFallback;
22
23            pub use $crate::plugin::tables::data::FieldTypeId;
24        }
25    };
26}
27
28#[doc(hidden)]
29#[macro_export]
30macro_rules! table_export_use_internals {
31    () => {
32        use $crate::internals::tables::export::DynamicFieldValue;
33        use $crate::internals::tables::export::FieldDescriptor;
34        use $crate::internals::tables::export::FieldId;
35        use $crate::internals::tables::export::FieldRef;
36        use $crate::internals::tables::export::FieldTypeId;
37        use $crate::internals::tables::export::HasMetadata;
38        use $crate::internals::tables::export::Metadata;
39        use $crate::internals::tables::export::RefShared;
40        use $crate::internals::tables::export::StaticFieldCheck;
41        use $crate::internals::tables::export::StaticFieldFallback;
42        use $crate::internals::tables::export::StaticFieldGet;
43        use $crate::internals::tables::export::StaticFieldGetFallback;
44        use $crate::internals::tables::export::StaticFieldSet;
45        use $crate::internals::tables::export::StaticFieldSetFallback;
46        use $crate::internals::tables::export::TableMetadata;
47
48        use $crate::api::ss_plugin_table_fieldinfo;
49        use $crate::phf;
50    };
51}
52
53#[doc(hidden)]
54#[macro_export]
55macro_rules! impl_export_table_get {
56    (
57        $self:ident,
58        static: $($i:literal: $field_name:ident,)*
59    ) => {
60        fn get(
61            &$self,
62            key: FieldId,
63            type_id: FieldTypeId,
64            out: &mut $crate::api::ss_plugin_state_data,
65        ) -> Result<(), $crate::anyhow::Error> {
66            match key {
67                $(FieldId::Static($i) => StaticFieldGet(&$self.$field_name).static_field_get(type_id, out),)*
68                _ => $crate::anyhow::bail!("Unknown field")
69            }
70        }
71    };
72}
73
74#[doc(hidden)]
75#[macro_export]
76macro_rules! impl_export_table_set {
77    (
78        $self:ident,
79        static: $($i:literal: $field_name:ident,)*
80    ) => {
81        fn set(
82            &mut $self,
83            key: FieldId,
84            value: DynamicFieldValue)
85            -> std::result::Result<(), $crate::anyhow::Error> {
86            match key {
87                $(FieldId::Static($i) => StaticFieldSet(&mut $self.$field_name).static_field_set(value),)*
88                _ => $crate::anyhow::bail!("Unknown field")
89            }
90        }
91    };
92}
93
94#[doc(hidden)]
95#[macro_export]
96macro_rules! impl_export_table {
97    (for $name:ident {
98        $([$i:literal] $field_tag:literal ($field_name_bstr:literal) as $field_name:ident: $field_type:ty)*
99    }) => {
100        const _: () = {
101            $crate::table_export_use_internals!();
102
103            static STATIC_FIELDS: $crate::phf::Map<&'static [u8], std::option::Option<FieldDescriptor>> = $crate::phf::phf_map! {
104                $($field_name_bstr => FieldDescriptor::maybe_new(
105                    FieldId::Static($i),
106                    StaticFieldCheck::<$field_type>::MAYBE_TYPE_ID,
107                    StaticFieldCheck::<$field_type>::READONLY,
108                ),)*
109            };
110
111            pub struct EntryMetadata {
112                $(pub $field_name: <$field_type as HasMetadata>::Metadata,)*
113            }
114
115            impl Metadata for EntryMetadata {
116                fn new() -> $crate::anyhow::Result<Self> {
117                    Ok(Self {
118                        $($field_name: Metadata::new()?,)*
119                    })
120                }
121            }
122
123            impl TableMetadata for EntryMetadata {
124                fn get_field(&self, name: &::std::ffi::CStr) ->
125                    std::option::Option<FieldRef>
126                {
127                    let field = STATIC_FIELDS.get(name.to_bytes_with_nul())?.as_ref()?;
128                    Some(FieldRef::Static(field))
129                }
130
131                fn add_field(
132                    &mut self,
133                    name: &std::ffi::CStr,
134                    field_type: FieldTypeId,
135                    read_only: bool,
136                ) ->
137                    std::option::Option<FieldRef>
138                {
139                    None
140                }
141
142                fn list_fields(&self) -> std::vec::Vec<ss_plugin_table_fieldinfo> {
143                    STATIC_FIELDS
144                        .entries()
145                        .filter_map(|(name, maybe_field)| {
146                            match maybe_field {
147                                Some(field) => Some(field.to_raw(name)),
148                                None => None,
149                            }
150                        })
151                        .collect()
152                }
153            }
154
155            impl HasMetadata for $name {
156                type Metadata = RefShared<EntryMetadata>;
157
158                fn new_with_metadata(tag: &'static std::ffi::CStr, meta: &Self::Metadata) -> ::std::result::Result<Self, $crate::anyhow::Error> {
159                    Ok(Self {
160                       $($field_name: HasMetadata::new_with_metadata($field_tag, &meta.read().$field_name)?,)*
161                    })
162                }
163            }
164
165            impl $crate::internals::tables::export::Entry for $name {
166                $crate::impl_export_table_get!(
167                    self,
168                    static: $($i: $field_name,)*
169                );
170                $crate::impl_export_table_set!(
171                    self,
172                    static: $($i: $field_name,)*
173                );
174            }
175        };
176    };
177}