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