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
use std::any::{type_name, Any};
use crate::protocol::Event;
use crate::ClientOptions;
/// Integration abstraction.
///
/// An Integration in sentry has two primary purposes.
/// It can act as an *Event Source*, which will capture new events;
/// or as an *Event Processor*, which can modify every `Event` flowing through
/// the pipeline.
///
/// # Examples
///
/// ```
/// use sentry::protocol::{Event, Level};
/// use sentry::ClientOptions;
///
/// struct MyProcessorIntegration {
///     override_environment: &'static str,
///     override_level: Level,
/// }
///
/// impl sentry::Integration for MyProcessorIntegration {
///     fn setup(&self, options: &mut ClientOptions) {
///         options.environment = Some(self.override_environment.into());
///     }
///     fn process_event(
///         &self,
///         mut event: Event<'static>,
///         _options: &ClientOptions,
///     ) -> Option<Event<'static>> {
///         event.level = self.override_level;
///         Some(event)
///     }
/// }
///
/// let options = ClientOptions::new().add_integration(MyProcessorIntegration {
///     override_environment: "my_env",
///     override_level: Level::Error,
/// });
///
/// let events = sentry::test::with_captured_events_options(
///     || {
///         sentry::capture_message("some message", Level::Info);
///     },
///     options,
/// );
/// let captured_event = events.into_iter().next().unwrap();
///
/// assert_eq!(captured_event.level, Level::Error);
/// assert_eq!(captured_event.environment, Some("my_env".into()));
/// ```
// NOTE: we need `Any` here so that the `TypeId` machinery works correctly.
pub trait Integration: Sync + Send + Any + AsAny {
    /// Name of this integration.
    ///
    /// This will be added to the SDK information sent to sentry.
    fn name(&self) -> &'static str {
        type_name::<Self>()
    }
    /// Called whenever the integration is attached to a Client.
    fn setup(&self, options: &mut ClientOptions) {
        let _ = options;
    }
    /// The Integrations Event Processor Hook.
    ///
    /// An integration can process, or even completely drop an `Event`.
    /// Examples include adding or processing a backtrace, obfuscate some
    /// personal information, or add additional information.
    fn process_event(
        &self,
        event: Event<'static>,
        options: &ClientOptions,
    ) -> Option<Event<'static>> {
        let _ = options;
        Some(event)
    }
}
// This is needed as a workaround to be able to safely downcast integrations
#[doc(hidden)]
pub trait AsAny {
    fn as_any(&self) -> &dyn Any;
}
impl<T: Any> AsAny for T {
    fn as_any(&self) -> &dyn Any {
        self
    }
}