relay_event_schema/protocol/contexts/
user_report_v2.rs

1use relay_protocol::{Annotated, Empty, FromValue, IntoValue, Object, Value};
2
3use crate::processor::ProcessValue;
4
5/// Feedback context.
6///
7/// This contexts contains user feedback specific attributes.
8/// We don't PII scrub contact_email as that is provided by the user.
9/// TODO(jferg): rename to FeedbackContext once old UserReport logic is deprecated.
10#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)]
11pub struct UserReportV2Context {
12    /// The feedback message which contains what the user has to say.
13    pub message: Annotated<String>,
14
15    /// an email optionally provided by the user, which can be different from user.email
16    #[metastructure(pii = "false")]
17    pub contact_email: Annotated<String>,
18    /// Additional arbitrary fields for forwards compatibility.
19    #[metastructure(additional_properties, retain = true)]
20    pub other: Object<Value>,
21}
22
23impl super::DefaultContext for UserReportV2Context {
24    fn default_key() -> &'static str {
25        "feedback"
26    }
27
28    fn from_context(context: super::Context) -> Option<Self> {
29        match context {
30            super::Context::UserReportV2(c) => Some(*c),
31            _ => None,
32        }
33    }
34
35    fn cast(context: &super::Context) -> Option<&Self> {
36        match context {
37            super::Context::UserReportV2(c) => Some(c),
38            _ => None,
39        }
40    }
41
42    fn cast_mut(context: &mut super::Context) -> Option<&mut Self> {
43        match context {
44            super::Context::UserReportV2(c) => Some(c),
45            _ => None,
46        }
47    }
48
49    fn into_context(self) -> super::Context {
50        super::Context::UserReportV2(Box::new(self))
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57    use crate::protocol::Context;
58
59    #[test]
60    fn test_feedback_context() {
61        let json = r#"{
62  "message": "test message",
63  "contact_email": "test@test.com",
64  "type": "feedback"
65}"#;
66        let context = Annotated::new(Context::UserReportV2(Box::new(UserReportV2Context {
67            message: Annotated::new("test message".to_string()),
68            contact_email: Annotated::new("test@test.com".to_string()),
69            other: Object::default(),
70        })));
71
72        assert_eq!(context, Annotated::from_json(json).unwrap());
73        assert_eq!(json, context.to_json_pretty().unwrap());
74    }
75}