1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//! The [`Event`] trait tying a struct to its schema and its bytes.
//!
//! `#[derive(Event)]` implements this for a `#[repr(C)]` struct. Two things make a type an event:
//!
//! * It is described by a compile-time [`EventSchema`] (so the dump is self-describing), exposed as
//! the associated [`Event::SCHEMA`] and its [`EventId`] as [`Event::ID`].
//! * It is plain-old-data the recorder can capture with a single memcpy. We express that by
//! requiring [`zerocopy::IntoBytes`] + [`zerocopy::Immutable`]: the field bytes are *borrowed*
//! straight from the struct via [`as_bytes`](zerocopy::IntoBytes::as_bytes) with no
//! serialization or allocation, and [`Ring::push_event`](crate::ring::Ring::push_event) copies
//! `[event_id u64][fields]` directly into its preallocated, reserved slice. The `IntoBytes`
//! derive *also* rejects any layout with implicit padding — precisely the layouts the schema
//! reader could not describe — so the bound doubles as the padding check the derive would
//! otherwise have to do by hand.
use crate::;
use ;
/// A type that can be recorded by backbeat.
///
/// Implemented by `#[derive(Event)]`; see the [module docs](self) for the meaning of the bounds.
/// The recorder captures one with [`Ring::push_event`](crate::ring::Ring::push_event), which writes
/// the record without touching the heap.
/// A Rust enum usable as an event field.
///
/// Implemented by `#[derive(EventEnum)]` on a fieldless `#[repr(u8|u16|u32|u64)]` enum. Instead of
/// hand-writing `#[event(enum_labels(...))]` on every field, you define the enum once with its
/// strong type and pass it around; a field of that type is automatically reflected as a
/// [`FieldType::Enum`](crate::schema::FieldType::Enum) whose value→label map comes from
/// [`LABELS`](EventEnum::LABELS). The [`IntoBytes`] + [`Immutable`] bounds let the enum sit inline
/// in a `#[repr(C)]` event with no serialization.
///
/// ```ignore
/// use backbeat::EventEnum;
/// use backbeat::zerocopy::{Immutable, IntoBytes};
///
/// #[derive(EventEnum, IntoBytes, Immutable, Clone, Copy)]
/// #[repr(u8)]
/// enum Direction { Inbound = 0, Outbound = 1 }
/// ```
/// How a Rust type appears as an event field, resolved at compile time.
///
/// This is the seam that lets `#[derive(Event)]` reflect a field *without knowing the field's type*:
/// it emits `<FieldTypeOfField as FieldTy>::FIELD_TYPE` / `::LABELS`, and the right impl is selected
/// at const-eval. The primitives ([`u8`]…[`i64`], [`bool`]) and `[u8; N]` have built-in impls here;
/// every `#[derive(EventEnum)]` type gets one via the [blanket impl](#impl-FieldTy-for-T). Fields
/// that are interned strings opt in with `#[event(interned)]` instead of going through `FieldTy`.
///
/// Implementors must be plain inline bytes ([`IntoBytes`] + [`Immutable`]) since the field sits
/// directly in the `#[repr(C)]` event.
/// Every `EventEnum` is usable as a field: an [`Enum`](crate::schema::FieldType::Enum) of its repr
/// width carrying its labels.
/// Implements [`FieldTy`] for a built-in scalar mapping to a [`FieldType`] variant.
impl_field_ty!
/// A fixed-width byte array field, rendered as hex.