relay_event_schema/processor/
traits.rs

1// This module only defines traits, every parameter is used by definition
2#![allow(unused_variables)]
3
4use std::fmt::Debug;
5
6use relay_protocol::{FiniteF64, FromValue, IntoValue, Meta};
7
8use crate::processor::{ProcessingState, ValueType, process_value};
9
10/// Used to indicate how to handle an annotated value in a callback.
11#[must_use = "This `ProcessingAction` must be handled by `Annotated::apply`"]
12#[derive(Copy, Clone, Debug, PartialEq, Eq, thiserror::Error)]
13pub enum ProcessingAction {
14    /// Discards the value entirely.
15    #[error("value should be hard-deleted (unreachable, should not surface as error!)")]
16    DeleteValueHard,
17
18    /// Discards the value entirely, but leaves a remark.
19    ///
20    /// The contained string is used as the "rule id" in the remark.
21    #[error("value should be hard-deleted (unreachable, should not surface as error!)")]
22    DeleteValueWithRemark(&'static str),
23
24    /// Discards the value and moves it into meta's `original_value`.
25    #[error("value should be hard-deleted (unreachable, should not surface as error!)")]
26    DeleteValueSoft,
27
28    /// The event is invalid (needs to bubble up)
29    #[error("invalid transaction event: {0}")]
30    InvalidTransaction(&'static str),
31}
32
33/// The result of running a processor on a value implementing `ProcessValue`.
34pub type ProcessingResult = Result<(), ProcessingAction>;
35
36macro_rules! process_method {
37    ($name: ident, $ty:ident $(::$path:ident)*) => {
38        process_method!($name, $ty $(::$path)* <>);
39    };
40
41    ($name: ident, $ty:ident $(::$path:ident)* < $($param:ident),* > $(, $param_req_key:ident : $param_req_trait:path)*) => {
42        #[inline]
43        fn $name<$($param),*>(
44            &mut self,
45            value: &mut $ty $(::$path)* <$($param),*>,
46            meta: &mut Meta,
47            state: &ProcessingState<'_>,
48        ) -> ProcessingResult
49        where
50            $($param: ProcessValue),*
51            $(, $param_req_key : $param_req_trait)*
52        {
53            value.process_child_values(self, state)?;
54            Ok(())
55        }
56    };
57}
58
59/// A trait for processing processable values.
60pub trait Processor: Sized {
61    #[inline]
62    fn before_process<T: ProcessValue>(
63        &mut self,
64        value: Option<&T>,
65        meta: &mut Meta,
66        state: &ProcessingState<'_>,
67    ) -> ProcessingResult {
68        Ok(())
69    }
70
71    #[inline]
72    fn after_process<T: ProcessValue>(
73        &mut self,
74        value: Option<&T>,
75        meta: &mut Meta,
76        state: &ProcessingState<'_>,
77    ) -> ProcessingResult {
78        Ok(())
79    }
80
81    process_method!(process_string, String);
82    process_method!(process_u64, u64);
83    process_method!(process_i64, i64);
84    process_method!(process_f64, f64);
85    process_method!(process_finite_f64, FiniteF64);
86    process_method!(process_bool, bool);
87
88    process_method!(process_value, relay_protocol::Value);
89    process_method!(process_array, relay_protocol::Array<T>);
90    process_method!(process_object, relay_protocol::Object<T>);
91
92    process_method!(
93        process_pairlist,
94        crate::protocol::PairList<T>,
95        T: crate::protocol::AsPair
96    );
97    process_method!(process_values, crate::protocol::Values<T>);
98    process_method!(process_timestamp, crate::protocol::Timestamp);
99
100    process_method!(process_event, crate::protocol::Event);
101    process_method!(process_replay, crate::protocol::Replay);
102    process_method!(process_exception, crate::protocol::Exception);
103    process_method!(process_raw_stacktrace, crate::protocol::RawStacktrace);
104    process_method!(process_stacktrace, crate::protocol::Stacktrace);
105    process_method!(process_frame, crate::protocol::Frame);
106    process_method!(process_request, crate::protocol::Request);
107    process_method!(process_user, crate::protocol::User);
108    process_method!(process_client_sdk_info, crate::protocol::ClientSdkInfo);
109    process_method!(process_debug_meta, crate::protocol::DebugMeta);
110    process_method!(process_debug_image, crate::protocol::DebugImage);
111    process_method!(process_geo, crate::protocol::Geo);
112    process_method!(process_logentry, crate::protocol::LogEntry);
113    process_method!(process_thread, crate::protocol::Thread);
114    process_method!(process_context, crate::protocol::Context);
115    process_method!(process_breadcrumb, crate::protocol::Breadcrumb);
116    process_method!(process_template_info, crate::protocol::TemplateInfo);
117    process_method!(process_header_name, crate::protocol::HeaderName);
118    process_method!(process_ourlog, crate::protocol::OurLog);
119    process_method!(process_trace_metric, crate::protocol::TraceMetric);
120    process_method!(process_span, crate::protocol::Span);
121    process_method!(process_trace_context, crate::protocol::TraceContext);
122    process_method!(process_native_image_path, crate::protocol::NativeImagePath);
123    process_method!(process_contexts, crate::protocol::Contexts);
124    process_method!(process_attributes, crate::protocol::Attributes);
125
126    fn process_other(
127        &mut self,
128        other: &mut relay_protocol::Object<relay_protocol::Value>,
129        state: &ProcessingState<'_>,
130    ) -> ProcessingResult {
131        for (key, value) in other {
132            process_value(
133                value,
134                self,
135                &state.enter_borrowed(
136                    key.as_str(),
137                    state.inner_attrs(),
138                    ValueType::for_field(value),
139                ),
140            )?;
141        }
142
143        Ok(())
144    }
145}
146
147#[doc(inline)]
148pub use enumset::{EnumSet, enum_set};
149
150/// A recursively processable value.
151pub trait ProcessValue: FromValue + IntoValue + Debug + Clone + std::fmt::Debug {
152    /// Returns the type of the value.
153    #[inline]
154    fn value_type(&self) -> EnumSet<ValueType> {
155        EnumSet::empty()
156    }
157
158    /// Executes a processor on this value.
159    #[inline]
160    fn process_value<P>(
161        &mut self,
162        meta: &mut Meta,
163        processor: &mut P,
164        state: &ProcessingState<'_>,
165    ) -> ProcessingResult
166    where
167        P: Processor,
168    {
169        self.process_child_values(processor, state)
170    }
171
172    /// Recurses into children of this value.
173    #[inline]
174    fn process_child_values<P>(
175        &mut self,
176        processor: &mut P,
177        state: &ProcessingState<'_>,
178    ) -> ProcessingResult
179    where
180        P: Processor,
181    {
182        Ok(())
183    }
184}
185
186pub use relay_event_derive::ProcessValue;