use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::{PROTOCOL_VERSION, source::SourceId};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AttachmentManifest {
pub key: String,
pub filename: Option<String>,
pub content_type: String,
pub len: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct BuildInfo {
pub git_sha: String,
pub profile: String,
pub target_triple: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum CrashKind {
Minidump,
PanicTarball,
RustcIce,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CrashMetadata {
pub schema_version: u32,
pub source: SourceId,
pub timestamp: DateTime<Utc>,
pub kind: CrashKind,
pub build: BuildInfo,
pub panic_text: Option<String>,
pub context: serde_json::Value,
pub attachments: Vec<AttachmentManifest>,
}
impl CrashMetadata {
#[must_use]
pub const fn new(
source: SourceId,
timestamp: DateTime<Utc>,
kind: CrashKind,
build: BuildInfo,
context: serde_json::Value,
) -> Self {
Self {
schema_version: PROTOCOL_VERSION,
source,
timestamp,
kind,
build,
panic_text: None,
context,
attachments: Vec::new(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CrashEnvelope {
pub metadata: CrashMetadata,
pub dump: Vec<u8>,
pub attachments: Vec<CrashAttachment>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CrashAttachment {
pub key: String,
pub content_type: String,
pub bytes: Vec<u8>,
}
#[derive(Debug, thiserror::Error)]
pub enum ProtocolError {
#[error("crash metadata JSON error: {0}")]
Json(#[from] serde_json::Error),
#[cfg(feature = "multipart")]
#[error("multipart parse error: {0}")]
Multipart(#[from] multer::Error),
#[cfg(feature = "multipart")]
#[error("multipart I/O error: {0}")]
Io(#[from] std::io::Error),
#[cfg(feature = "multipart")]
#[error("missing multipart part `{0}`")]
MissingPart(&'static str),
#[cfg(feature = "multipart")]
#[error("invalid multipart part name")]
InvalidPartName,
#[cfg(feature = "multipart")]
#[error("invalid multipart payload: {0}")]
InvalidMultipart(String),
}