relay_event_schema/protocol/
trace_attachment.rs

1use std::fmt;
2use std::ops::Deref;
3
4use relay_protocol::{Annotated, Empty, FromValue, IntoValue, Object, SkipSerialization, Value};
5use serde::Serializer;
6
7use crate::processor::ProcessValue;
8use crate::protocol::{Attributes, Timestamp, TraceId};
9
10use uuid::Uuid;
11
12/// Metadata for a trace attachment.
13#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)]
14pub struct TraceAttachmentMeta {
15    /// The ID of the trace that the attachment belongs to.
16    #[metastructure(required = true, nonempty = true, trim = false)]
17    pub trace_id: Annotated<TraceId>,
18
19    /// Unique identifier for this attachment.
20    #[metastructure(required = true, nonempty = true, trim = false)]
21    pub attachment_id: Annotated<AttachmentId>,
22
23    /// Timestamp when the attachment was created.
24    #[metastructure(required = true, trim = false)]
25    pub timestamp: Annotated<Timestamp>,
26
27    /// Original filename of the attachment.
28    #[metastructure(pii = "true", max_chars = 256, max_chars_allowance = 40, trim = false)]
29    pub filename: Annotated<String>,
30
31    /// Content type of the attachment body.
32    #[metastructure(required = true, max_chars = 128, trim = false)]
33    pub content_type: Annotated<String>,
34
35    /// Arbitrary attributes on a trace attachment.
36    #[metastructure(pii = "maybe")]
37    pub attributes: Annotated<Attributes>,
38
39    /// Additional arbitrary fields for forwards compatibility.
40    #[metastructure(additional_properties, pii = "maybe")]
41    pub other: Object<Value>,
42}
43
44#[derive(Clone, Default, PartialEq, Empty, FromValue, ProcessValue)]
45pub struct AttachmentId(Uuid);
46
47impl AttachmentId {
48    /// Creates a new attachment ID. Only used in tests.
49    pub fn random() -> Self {
50        Self(Uuid::now_v7())
51    }
52}
53
54impl Deref for AttachmentId {
55    type Target = Uuid;
56
57    fn deref(&self) -> &Self::Target {
58        &self.0
59    }
60}
61
62impl fmt::Display for AttachmentId {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        write!(f, "{}", self.0.as_simple())
65    }
66}
67
68impl fmt::Debug for AttachmentId {
69    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70        write!(f, "AttachmentId(\"{}\")", self.0.as_simple())
71    }
72}
73
74impl IntoValue for AttachmentId {
75    fn into_value(self) -> Value
76    where
77        Self: Sized,
78    {
79        Value::String(self.to_string())
80    }
81
82    fn serialize_payload<S>(&self, s: S, _behavior: SkipSerialization) -> Result<S::Ok, S::Error>
83    where
84        Self: Sized,
85        S: Serializer,
86    {
87        s.collect_str(self)
88    }
89}