1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8
9use crate::error::{Error, Result};
10use crate::TapMessage;
11
12#[derive(Debug, Clone, Serialize, Deserialize, TapMessage)]
14#[tap(generated_id)]
15#[tap(message_type = "https://tap.rsvp/schema/1.0#Error")]
16pub struct ErrorBody {
17 pub code: String,
19
20 pub description: String,
22
23 #[serde(skip_serializing_if = "Option::is_none")]
25 pub original_message_id: Option<String>,
26
27 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
29 pub metadata: HashMap<String, serde_json::Value>,
30}
31
32impl ErrorBody {
33 pub fn new(code: &str, description: &str) -> Self {
35 Self {
36 code: code.to_string(),
37 description: description.to_string(),
38 original_message_id: None,
39 metadata: HashMap::new(),
40 }
41 }
42
43 pub fn with_original_message(code: &str, description: &str, original_message_id: &str) -> Self {
45 Self {
46 code: code.to_string(),
47 description: description.to_string(),
48 original_message_id: Some(original_message_id.to_string()),
49 metadata: HashMap::new(),
50 }
51 }
52
53 pub fn with_metadata(mut self, key: &str, value: serde_json::Value) -> Self {
55 self.metadata.insert(key.to_string(), value);
56 self
57 }
58}
59
60impl ErrorBody {
61 pub fn validate_error(&self) -> Result<()> {
63 if self.code.is_empty() {
64 return Err(Error::Validation(
65 "Error code is required in ErrorBody".to_string(),
66 ));
67 }
68
69 if self.description.is_empty() {
70 return Err(Error::Validation(
71 "Error description is required in ErrorBody".to_string(),
72 ));
73 }
74
75 Ok(())
76 }
77}