relay_filter/
common.rs

1use std::borrow::Cow;
2use std::fmt;
3
4use serde::Serialize;
5
6/// Identifies which filter dropped an event for which reason.
7///
8/// Ported from Sentry's same-named "enum". The enum variants are fed into outcomes in kebap-case
9/// (e.g.  "browser-extensions")
10#[derive(Debug, Clone, Eq, PartialEq, Serialize, Hash)]
11pub enum FilterStatKey {
12    /// Filtered by ip address.
13    IpAddress,
14
15    /// Filtered by release name (version).
16    ReleaseVersion,
17
18    /// Filtered by error message.
19    ErrorMessage,
20
21    /// Filtered by browser extension.
22    BrowserExtensions,
23
24    /// Filtered by legacy browser version.
25    LegacyBrowsers,
26
27    /// Filtered due to localhost restriction.
28    Localhost,
29
30    /// Filtered as known web crawler.
31    WebCrawlers,
32
33    /// Filtered due to invalid CSP policy.
34    InvalidCsp,
35
36    /// Filtered due to the fact that it was a call to a filtered transaction
37    FilteredTransactions,
38
39    /// Filtered due to name being denied.
40    DeniedName,
41
42    /// Filtered due to the namespace being disabled.
43    DisabledNamespace,
44
45    /// Filtered due to a generic filter.
46    GenericFilter(String),
47}
48
49// An event grouped to a removed group.
50//
51// Not returned by any filters implemented in Rust.
52// DiscardedHash,
53
54// Invalid CORS header.
55//
56// NOTE: Although cors is in the Sentry's FilterStatKey enum it is used for
57// Invalid outcomes and therefore should logically belong to OutcomeInvalidReason
58// that is why it was commented here and moved to OutcomeInvalidReason enum
59// Cors,
60
61impl FilterStatKey {
62    /// Returns the string identifier of the filter stat key.
63    pub fn name(self) -> Cow<'static, str> {
64        Cow::Borrowed(match self {
65            FilterStatKey::IpAddress => "ip-address",
66            FilterStatKey::ReleaseVersion => "release-version",
67            FilterStatKey::ErrorMessage => "error-message",
68            FilterStatKey::BrowserExtensions => "browser-extensions",
69            FilterStatKey::LegacyBrowsers => "legacy-browsers",
70            FilterStatKey::Localhost => "localhost",
71            FilterStatKey::WebCrawlers => "web-crawlers",
72            FilterStatKey::InvalidCsp => "invalid-csp",
73            FilterStatKey::FilteredTransactions => "filtered-transaction",
74            FilterStatKey::DeniedName => "denied-name",
75            FilterStatKey::DisabledNamespace => "disabled-namespace",
76            FilterStatKey::GenericFilter(filter_identifier) => {
77                return Cow::Owned(filter_identifier);
78            }
79        })
80    }
81}
82
83impl fmt::Display for FilterStatKey {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        write!(f, "{}", self.clone().name())
86    }
87}
88
89impl<'a> TryFrom<&'a str> for FilterStatKey {
90    type Error = &'a str;
91
92    fn try_from(value: &'a str) -> Result<Self, Self::Error> {
93        Ok(match value {
94            "ip-address" => FilterStatKey::IpAddress,
95            "release-version" => FilterStatKey::ReleaseVersion,
96            "error-message" => FilterStatKey::ErrorMessage,
97            "browser-extensions" => FilterStatKey::BrowserExtensions,
98            "legacy-browsers" => FilterStatKey::LegacyBrowsers,
99            "localhost" => FilterStatKey::Localhost,
100            "web-crawlers" => FilterStatKey::WebCrawlers,
101            "invalid-csp" => FilterStatKey::InvalidCsp,
102            "filtered-transaction" => FilterStatKey::FilteredTransactions,
103            other => FilterStatKey::GenericFilter(other.to_string()),
104        })
105    }
106}