falco_event/events/
payload.rs

1use crate::events::EventMetadata;
2use crate::fields::FromBytesError;
3use std::collections::BTreeSet;
4use std::io::Write;
5use thiserror::Error;
6
7#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
8pub enum EventDirection {
9    Entry,
10    Exit,
11}
12
13pub trait EventPayload {
14    const ID: u16;
15    const SOURCE: Option<&'static str>;
16}
17
18pub const fn event_direction(event_type_id: u16) -> EventDirection {
19    match event_type_id % 2 {
20        0 => EventDirection::Entry,
21        1 => EventDirection::Exit,
22        _ => unreachable!(),
23    }
24}
25
26pub trait AnyEventPayload {
27    const SOURCES: &'static [Option<&'static str>];
28    const EVENT_TYPES: &'static [u16];
29
30    /// Get all the event sources for this payload type
31    ///
32    /// This is intended for internal use only. If all the items in `SOURCES` are `Some()`,
33    /// the function returns the inner strings with duplicates removed. If any item is `None`
34    /// (indicating a supported event may come from any source), an empty vector is returned
35    /// (again, indicating all sources).
36    fn event_sources() -> Vec<&'static str> {
37        let mut sources = BTreeSet::new();
38        for source in Self::SOURCES {
39            if let Some(source) = source {
40                sources.insert(*source);
41            } else {
42                return Vec::new();
43            }
44        }
45
46        sources.into_iter().collect()
47    }
48}
49
50impl<T: EventPayload> AnyEventPayload for T {
51    const SOURCES: &'static [Option<&'static str>] = const {
52        match T::SOURCE {
53            Some(s) => &[Some(s)],
54            None => &[],
55        }
56    };
57    const EVENT_TYPES: &'static [u16] = &[T::ID];
58}
59#[derive(Debug, Error)]
60pub enum PayloadFromBytesError {
61    /// Failed to parse a particular field
62    #[error("failed to parse field {0}")]
63    NamedField(&'static str, #[source] FromBytesError),
64
65    /// Type mismatch
66    #[error("type mismatch")]
67    TypeMismatch,
68
69    /// Truncated event
70    #[error("truncated event (wanted {wanted}, got {got})")]
71    TruncatedEvent { wanted: usize, got: usize },
72
73    /// Unsupported event type
74    #[error("unsupported event type {0}")]
75    UnsupportedEventType(u16),
76}
77
78pub trait PayloadToBytes {
79    fn binary_size(&self) -> usize;
80
81    fn write<W: Write>(&self, metadata: &EventMetadata, writer: W) -> std::io::Result<()>;
82}