co_didcomm/messages/headers/
didcomm.rs1use std::collections::HashMap;
2
3use crate::{Error, PriorClaims, Thread};
4
5#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
8pub struct DidCommHeader {
9 pub id: String,
10
11 #[serde(skip_serializing_if = "Option::is_none")]
12 pub thid: Option<String>,
13
14 #[serde(skip_serializing_if = "Option::is_none")]
15 pub pthid: Option<String>,
16
17 #[serde(rename = "type")]
18 pub m_type: String,
19
20 #[serde(default, skip_serializing_if = "Vec::is_empty")]
21 pub to: Vec<String>,
22
23 pub from: Option<String>,
24
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub created_time: Option<u64>,
27
28 #[serde(skip_serializing_if = "Option::is_none")]
29 pub expires_time: Option<u64>,
30 #[serde(skip_serializing_if = "Option::is_none")]
33 from_prior: Option<PriorClaims>,
34
35 #[serde(skip_serializing_if = "Option::is_none", rename = "~thread")]
37 pub thread: Option<Thread>,
38 #[serde(flatten, skip_serializing_if = "HashMap::is_empty")]
39 pub(crate) other: HashMap<String, String>,
40}
41
42impl DidCommHeader {
43 pub fn new() -> Self {
45 DidCommHeader {
46 id: DidCommHeader::gen_random_id(),
47 thid: None,
48 pthid: None,
49 m_type: "JWM".into(),
50 to: vec![String::default()],
51 from: Some(String::default()),
52 created_time: None,
53 expires_time: None,
54 from_prior: None,
55 thread: None,
56 other: HashMap::new(),
57 }
58 }
59
60 pub fn gen_random_id() -> String {
63 uuid::Uuid::new_v4().to_string()
64 }
65
66 pub fn get_message_uri(&self) -> String {
69 format!(
70 "didcomm://{}{}{}",
71 self.id,
72 self.thid.clone().unwrap_or_default(),
73 self.pthid.clone().unwrap_or_default(),
74 )
75 }
76
77 pub fn reply_to(&mut self, sender_header: &Self) {
84 match sender_header.thread {
85 Some(ref thread) if thread.is_implicit_reply(&sender_header.id) => {
86 let thid = sender_header.thread.as_ref().unwrap().thid.clone();
87 self.thread = Some(Thread::implicit_reply(&thid));
89 self.thid = Some(thid);
90 }
91 _ => {
92 self.thid = sender_header.thid.clone();
93 self.pthid = sender_header.pthid.clone();
94 }
95 };
96 self.to.push(sender_header.from.clone().unwrap_or_default());
97 }
98
99 pub fn from_prior(&self) -> Option<&PriorClaims> {
101 self.from_prior.as_ref()
102 }
103
104 pub fn forward(
106 to: Vec<String>,
107 from: Option<String>,
108 expires_time: Option<u64>,
109 ) -> Result<Self, Error> {
110 Ok(DidCommHeader {
111 to,
112 from,
113 created_time: crate::helpers::now_epoch_secs(),
114 expires_time,
115 ..DidCommHeader::new()
116 })
117 }
118}
119
120impl Default for DidCommHeader {
121 fn default() -> Self {
122 DidCommHeader::new()
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn reply_to_can_use_decorate_if_present() {
132 let _header = DidCommHeader::default();
133 }
134}