ftth_rsipstack/dialog/
mod.rs1use crate::{Error, Result};
2use crate::rsip;
3use rsip::{
4 prelude::{HeadersExt, UntypedHeader},
5 Request, Response,
6};
7
8pub mod authenticate;
9pub mod client_dialog;
10pub mod dialog;
11pub mod dialog_layer;
12pub mod invitation;
13pub mod registration;
14pub mod server_dialog;
15
16#[cfg(test)]
17mod tests;
18
19#[derive(Clone, Debug)]
50pub struct DialogId {
51 pub call_id: String,
52 pub from_tag: String,
53 pub to_tag: String,
54}
55
56impl PartialEq for DialogId {
57 fn eq(&self, other: &DialogId) -> bool {
58 if self.call_id != other.call_id {
59 return false;
60 }
61 if self.from_tag == other.from_tag && self.to_tag == other.to_tag {
62 return true;
63 }
64 if self.from_tag == other.to_tag && self.to_tag == other.from_tag {
65 return true;
66 }
67 false
68 }
69}
70
71impl Eq for DialogId {}
72impl std::hash::Hash for DialogId {
73 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
74 self.call_id.hash(state);
75 if self.from_tag > self.to_tag {
76 self.from_tag.hash(state);
77 self.to_tag.hash(state);
78 } else {
79 self.to_tag.hash(state);
80 self.from_tag.hash(state);
81 }
82 }
83}
84
85impl TryFrom<&Request> for DialogId {
86 type Error = crate::Error;
87
88 fn try_from(request: &Request) -> Result<Self> {
89 let call_id = request.call_id_header()?.value().to_string();
90
91 let from_tag = match request.from_header()?.tag()? {
92 Some(tag) => tag.value().to_string(),
93 None => return Err(Error::Error("from tag not found".to_string())),
94 };
95
96 let to_tag = match request.to_header()?.tag()? {
97 Some(tag) => tag.value().to_string(),
98 None => "".to_string(),
99 };
100
101 Ok(DialogId {
102 call_id,
103 from_tag,
104 to_tag,
105 })
106 }
107}
108
109impl TryFrom<&Response> for DialogId {
110 type Error = crate::Error;
111
112 fn try_from(resp: &Response) -> Result<Self> {
113 let call_id = resp.call_id_header()?.value().to_string();
114
115 let from_tag = match resp.from_header()?.tag()? {
116 Some(tag) => tag.value().to_string(),
117 None => return Err(Error::Error("from tag not found".to_string())),
118 };
119
120 let to_tag = match resp.to_header()?.tag()? {
121 Some(tag) => tag.value().to_string(),
122 None => return Err(Error::Error("to tag not found".to_string())),
123 };
124
125 Ok(DialogId {
126 call_id,
127 from_tag,
128 to_tag,
129 })
130 }
131}
132
133impl std::fmt::Display for DialogId {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 if self.from_tag > self.to_tag {
136 write!(f, "{}-{}-{}", self.call_id, self.from_tag, self.to_tag)
137 } else {
138 write!(f, "{}-{}-{}", self.call_id, self.to_tag, self.from_tag)
139 }
140 }
141}