ftth_rsip/message/
sip_message.rs1#[doc(hidden)]
2pub use tokenizer::Tokenizer;
3
4use super::{request, response};
5use crate::{common::Version, Error, Headers, Request, Response};
6use std::convert::{TryFrom, TryInto};
7
8#[derive(Debug, PartialEq, Eq, Clone)]
23pub enum SipMessage {
24 Request(Request),
25 Response(Response),
26}
27
28impl SipMessage {
29 pub fn is_request(&self) -> bool {
30 matches!(self, Self::Request(_))
31 }
32
33 pub fn is_response(&self) -> bool {
34 matches!(self, Self::Response(_))
35 }
36
37 pub fn version(&self) -> &Version {
38 match self {
39 Self::Request(request) => request.version(),
40 Self::Response(response) => response.version(),
41 }
42 }
43
44 pub fn body(&self) -> &Vec<u8> {
45 match self {
46 Self::Request(request) => request.body(),
47 Self::Response(response) => response.body(),
48 }
49 }
50
51 pub fn body_mut(&mut self) -> &mut Vec<u8> {
52 match self {
53 Self::Request(request) => request.body_mut(),
54 Self::Response(response) => response.body_mut(),
55 }
56 }
57}
58
59impl From<Request> for SipMessage {
60 fn from(request: Request) -> Self {
61 Self::Request(request)
62 }
63}
64
65impl From<Response> for SipMessage {
66 fn from(response: Response) -> Self {
67 Self::Response(response)
68 }
69}
70
71impl super::HasHeaders for SipMessage {
72 fn headers(&self) -> &Headers {
73 match self {
74 Self::Request(request) => request.headers(),
75 Self::Response(response) => response.headers(),
76 }
77 }
78
79 fn headers_mut(&mut self) -> &mut Headers {
80 match self {
81 Self::Request(request) => request.headers_mut(),
82 Self::Response(response) => response.headers_mut(),
83 }
84 }
85}
86
87impl std::fmt::Display for SipMessage {
88 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 match self {
90 Self::Request(request) => write!(f, "{}", request),
91 Self::Response(response) => write!(f, "{}", response),
92 }
93 }
94}
95
96impl TryFrom<&[u8]> for SipMessage {
97 type Error = Error;
98
99 fn try_from(from: &[u8]) -> Result<Self, Self::Error> {
100 Tokenizer::tokenize(from)?.1.try_into()
101 }
102}
103
104impl TryFrom<Vec<u8>> for SipMessage {
105 type Error = Error;
106
107 fn try_from(from: Vec<u8>) -> Result<Self, Self::Error> {
108 Tokenizer::tokenize(&from)?.1.try_into()
109 }
110}
111
112impl TryFrom<&str> for SipMessage {
113 type Error = Error;
114
115 fn try_from(from: &str) -> Result<Self, Self::Error> {
116 Tokenizer::tokenize(from.as_bytes())?.1.try_into()
117 }
118}
119
120impl TryFrom<String> for SipMessage {
121 type Error = Error;
122
123 fn try_from(from: String) -> Result<Self, Self::Error> {
124 Tokenizer::tokenize(from.as_bytes())?.1.try_into()
125 }
126}
127
128impl TryFrom<bytes::Bytes> for SipMessage {
129 type Error = Error;
130
131 fn try_from(from: bytes::Bytes) -> Result<Self, Self::Error> {
132 Tokenizer::tokenize(&from)?.1.try_into()
133 }
134}
135
136impl From<SipMessage> for String {
137 fn from(msg: SipMessage) -> Self {
138 msg.to_string()
139 }
140}
141
142impl From<SipMessage> for Vec<u8> {
143 fn from(msg: SipMessage) -> Self {
144 msg.to_string().into_bytes()
145 }
146}
147
148impl From<SipMessage> for bytes::Bytes {
149 fn from(msg: SipMessage) -> Self {
150 bytes::Bytes::from(msg.to_string())
151 }
152}
153
154#[doc(hidden)]
155pub mod tokenizer {
156 use super::{request, response, SipMessage};
157 use crate::{Error, IResult};
158 use std::convert::TryInto;
159
160 impl<'a> TryInto<SipMessage> for Tokenizer<'a> {
161 type Error = Error;
162
163 fn try_into(self) -> Result<SipMessage, Error> {
164 match self {
165 Tokenizer::Request(tokenizer) => Ok(SipMessage::Request(tokenizer.try_into()?)),
166 Tokenizer::Response(tokenizer) => Ok(SipMessage::Response(tokenizer.try_into()?)),
167 }
168 }
169 }
170
171 #[derive(Debug, PartialEq, Eq)]
172 pub enum Tokenizer<'a> {
173 Request(request::Tokenizer<'a>),
174 Response(response::Tokenizer<'a>),
175 }
176
177 impl<'a> From<request::Tokenizer<'a>> for Tokenizer<'a> {
178 fn from(tokenizer: request::Tokenizer<'a>) -> Self {
179 Self::Request(tokenizer)
180 }
181 }
182
183 impl<'a> From<response::Tokenizer<'a>> for Tokenizer<'a> {
184 fn from(tokenizer: response::Tokenizer<'a>) -> Self {
185 Self::Response(tokenizer)
186 }
187 }
188
189 impl<'a> Tokenizer<'a> {
190 pub fn tokenize(part: &'a [u8]) -> IResult<Self> {
191 use nom::{branch::alt, combinator::map};
192
193 let (_, message) = alt((
194 map(response::Tokenizer::tokenize, |r| r.into()),
195 map(request::Tokenizer::tokenize, |r| r.into()),
196 ))(part)?;
197
198 Ok((&[], message))
199 }
200 }
201}