relay_pii/
redactions.rs

1//! Redactions for rules.
2use serde::{Deserialize, Serialize};
3
4fn default_replace_text() -> String {
5    "[Filtered]".into()
6}
7
8/// Replaces a value with a specific string.
9#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
10#[serde(rename_all = "camelCase")]
11pub struct ReplaceRedaction {
12    /// The replacement string.
13    #[serde(default = "default_replace_text")]
14    pub text: String,
15}
16
17impl From<String> for ReplaceRedaction {
18    fn from(text: String) -> ReplaceRedaction {
19        ReplaceRedaction { text }
20    }
21}
22
23impl Default for ReplaceRedaction {
24    fn default() -> Self {
25        ReplaceRedaction {
26            text: default_replace_text(),
27        }
28    }
29}
30
31/// Defines how replacements happen.
32#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Default)]
33#[serde(tag = "method", rename_all = "snake_case")]
34pub enum Redaction {
35    /// The default redaction for this operation (normally equivalent to `Remove`).
36    ///
37    /// The main difference to `Remove` is that if the redaction is explicitly
38    /// set to `Remove` it also applies in situations where a default
39    /// redaction is otherwise not passed down (for instance with `Multiple`).
40    #[default]
41    Default,
42    /// Removes the value and puts nothing in its place.
43    Remove,
44    /// Replaces the matched group with a new value.
45    Replace(ReplaceRedaction),
46    /// Overwrites the matched value by masking.
47    Mask,
48    /// Replaces the value with a hash
49    Hash,
50    /// Added for forward compatibility as catch-all variant.
51    #[serde(other, skip_serializing)]
52    Other,
53}
54
55#[cfg(test)]
56mod tests {
57
58    use super::*;
59
60    #[test]
61    fn test_redaction_deser_method() {
62        let json = r#"{"method": "replace", "text": "[filter]"}"#;
63
64        let deser: Redaction = serde_json::from_str(json).unwrap();
65        let redaction = Redaction::Replace(ReplaceRedaction {
66            text: "[filter]".to_string(),
67        });
68        assert!(deser == redaction);
69    }
70
71    #[test]
72    fn test_redaction_deser_other() {
73        let json = r#"{"method": "foo", "text": "[filter]"}"#;
74
75        let deser: Redaction = serde_json::from_str(json).unwrap();
76        assert!(matches!(deser, Redaction::Other));
77    }
78}