1use std::fmt;
23use serde::Deserialize;
45/// The different types an attachment can have.
6#[derive(Debug, Copy, Clone, Eq, PartialEq, Deserialize)]
7pub enum AttachmentType {
8#[serde(rename = "event.attachment")]
9/// (default) A standard attachment without special meaning.
10Attachment,
11/// A minidump file that creates an error event and is symbolicated. The
12 /// file should start with the `MDMP` magic bytes.
13#[serde(rename = "event.minidump")]
14Minidump,
15/// An Apple crash report file that creates an error event and is symbolicated.
16#[serde(rename = "event.applecrashreport")]
17AppleCrashReport,
18/// An XML file containing UE4 crash meta data. During event ingestion,
19 /// event contexts and extra fields are extracted from this file.
20#[serde(rename = "unreal.context")]
21UnrealContext,
22/// A plain-text log file obtained from UE4 crashes. During event ingestion,
23 /// the last logs are extracted into event breadcrumbs.
24#[serde(rename = "unreal.logs")]
25UnrealLogs,
26}
2728impl Default for AttachmentType {
29fn default() -> Self {
30Self::Attachment
31 }
32}
3334impl AttachmentType {
35/// Gets the string value Sentry expects for the attachment type.
36pub fn as_str(self) -> &'static str {
37match self {
38Self::Attachment => "event.attachment",
39Self::Minidump => "event.minidump",
40Self::AppleCrashReport => "event.applecrashreport",
41Self::UnrealContext => "unreal.context",
42Self::UnrealLogs => "unreal.logs",
43 }
44 }
45}
4647#[derive(Clone, PartialEq, Default)]
48/// Represents an attachment item.
49pub struct Attachment {
50/// The actual attachment data.
51pub buffer: Vec<u8>,
52/// The filename of the attachment.
53pub filename: String,
54/// The Content Type of the attachment
55pub content_type: Option<String>,
56/// The special type of this attachment.
57pub ty: Option<AttachmentType>,
58}
5960impl Attachment {
61/// Writes the attachment and its headers to the provided `Writer`.
62pub fn to_writer<W>(&self, writer: &mut W) -> std::io::Result<()>
63where
64W: std::io::Write,
65 {
66writeln!(
67 writer,
68r#"{{"type":"attachment","length":{length},"filename":"{filename}","attachment_type":"{at}","content_type":"{ct}"}}"#,
69 filename = self.filename,
70 length = self.buffer.len(),
71 at = self.ty.unwrap_or_default().as_str(),
72 ct = self
73.content_type
74 .as_ref()
75 .unwrap_or(&"application/octet-stream".to_string())
76 )?;
7778 writer.write_all(&self.buffer)?;
79Ok(())
80 }
81}
8283// Implement Debug manually, otherwise users will be sad when they get a dump
84// of decimal encoded bytes to their console
85impl fmt::Debug for Attachment {
86fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 f.debug_struct("Attachment")
88 .field("buffer", &self.buffer.len())
89 .field("filename", &self.filename)
90 .field("content_type", &self.content_type)
91 .field("type", &self.ty)
92 .finish()
93 }
94}