Skip to main content

tell_encoding/
lib.rs

1mod batch;
2mod event;
3mod helpers;
4mod log;
5mod metric;
6
7#[cfg(test)]
8mod batch_test;
9#[cfg(test)]
10mod event_test;
11#[cfg(test)]
12mod log_test;
13#[cfg(test)]
14mod metric_test;
15
16pub use batch::{encode_batch, encode_batch_into};
17pub use event::{encode_event, encode_event_data, encode_event_data_into};
18pub use log::{encode_log_data, encode_log_data_into, encode_log_entry};
19pub use metric::{encode_metric_data, encode_metric_data_into, encode_metric_entry};
20
21/// API key length in bytes (16 bytes = 32 hex chars).
22pub const API_KEY_LENGTH: usize = 16;
23
24/// UUID length in bytes.
25pub const UUID_LENGTH: usize = 16;
26
27/// IPv6 address length in bytes.
28pub const IPV6_LENGTH: usize = 16;
29
30/// Default protocol version (v1.0 = 100).
31pub const DEFAULT_VERSION: u8 = 100;
32
33/// Schema type for routing batches.
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35#[repr(u8)]
36pub enum SchemaType {
37    Unknown = 0,
38    Event = 1,
39    Log = 2,
40    Metric = 3,
41}
42
43impl SchemaType {
44    #[inline]
45    pub const fn as_u8(self) -> u8 {
46        self as u8
47    }
48}
49
50/// Event type for analytics events.
51#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
52#[repr(u8)]
53pub enum EventType {
54    #[default]
55    Unknown = 0,
56    Track = 1,
57    Identify = 2,
58    Group = 3,
59    Alias = 4,
60    Enrich = 5,
61    Context = 6,
62}
63
64impl EventType {
65    #[inline]
66    pub const fn as_u8(self) -> u8 {
67        self as u8
68    }
69}
70
71/// Log event type.
72#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
73#[repr(u8)]
74pub enum LogEventType {
75    Unknown = 0,
76    #[default]
77    Log = 1,
78    Enrich = 2,
79}
80
81impl LogEventType {
82    #[inline]
83    pub const fn as_u8(self) -> u8 {
84        self as u8
85    }
86}
87
88/// Log severity levels following RFC 5424 + trace.
89#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
90#[repr(u8)]
91pub enum LogLevel {
92    Emergency = 0,
93    Alert = 1,
94    Critical = 2,
95    Error = 3,
96    Warning = 4,
97    Notice = 5,
98    #[default]
99    Info = 6,
100    Debug = 7,
101    Trace = 8,
102}
103
104impl LogLevel {
105    #[inline]
106    pub const fn as_u8(self) -> u8 {
107        self as u8
108    }
109}
110
111/// Metric type — determines how to interpret the value.
112#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
113#[repr(u8)]
114pub enum MetricType {
115    #[default]
116    Unknown = 0,
117    /// Point-in-time value (cpu %, memory bytes, temperature).
118    Gauge = 1,
119    /// Cumulative or delta count (requests_total, bytes_sent).
120    Counter = 2,
121    /// Distribution with buckets (latency, request size).
122    Histogram = 3,
123}
124
125impl MetricType {
126    #[inline]
127    pub const fn as_u8(self) -> u8 {
128        self as u8
129    }
130}
131
132/// Aggregation temporality — how counter/histogram values relate to time.
133#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
134#[repr(u8)]
135pub enum Temporality {
136    #[default]
137    Unspecified = 0,
138    /// Total since process start (Prometheus-style).
139    Cumulative = 1,
140    /// Change since last report (StatsD-style).
141    Delta = 2,
142}
143
144impl Temporality {
145    #[inline]
146    pub const fn as_u8(self) -> u8 {
147        self as u8
148    }
149}
150
151/// Parameters for encoding a single event.
152pub struct EventParams<'a> {
153    pub event_type: EventType,
154    pub timestamp: u64,
155    pub service: Option<&'a str>,
156    pub device_id: Option<&'a [u8; UUID_LENGTH]>,
157    pub session_id: Option<&'a [u8; UUID_LENGTH]>,
158    pub event_name: Option<&'a str>,
159    pub payload: Option<&'a [u8]>,
160}
161
162/// Parameters for encoding a single log entry.
163pub struct LogEntryParams<'a> {
164    pub event_type: LogEventType,
165    pub session_id: Option<&'a [u8; UUID_LENGTH]>,
166    pub level: LogLevel,
167    pub timestamp: u64,
168    pub source: Option<&'a str>,
169    pub service: Option<&'a str>,
170    pub payload: Option<&'a [u8]>,
171}
172
173/// Parameters for encoding a single metric entry.
174pub struct MetricEntryParams<'a> {
175    pub metric_type: MetricType,
176    pub timestamp: u64,
177    pub name: &'a str,
178    pub value: f64,
179    pub source: Option<&'a str>,
180    pub service: Option<&'a str>,
181    pub labels: &'a [LabelParam<'a>],
182    pub temporality: Temporality,
183    pub histogram: Option<&'a HistogramParams>,
184    pub session_id: Option<&'a [u8; UUID_LENGTH]>,
185}
186
187/// A string key-value label for metric dimensions.
188pub struct LabelParam<'a> {
189    pub key: &'a str,
190    pub value: &'a str,
191}
192
193/// Histogram data for encoding.
194#[derive(Debug, Clone)]
195pub struct HistogramParams {
196    pub count: u64,
197    pub sum: f64,
198    pub min: f64,
199    pub max: f64,
200    /// Bucket boundaries and cumulative counts, sorted by `upper_bound`.
201    /// Use `f64::INFINITY` for the final catch-all bucket.
202    pub buckets: Vec<(f64, u64)>,
203}
204
205/// Parameters for encoding a batch.
206pub struct BatchParams<'a> {
207    pub api_key: &'a [u8; API_KEY_LENGTH],
208    pub schema_type: SchemaType,
209    pub version: u8,
210    pub batch_id: u64,
211    pub data: &'a [u8],
212}