oddity_rtsp_protocol/
message.rs

1use std::collections::BTreeMap;
2use std::fmt;
3use std::str::FromStr;
4
5use super::{parse::Parse, serialize::Serialize, Error};
6
7pub use bytes::Bytes;
8pub use http::uri::Uri;
9
10pub trait Message: Serialize + fmt::Display {
11    type Metadata: Parse;
12
13    fn new(metadata: Self::Metadata, headers: Headers, body: Option<Bytes>) -> Self;
14}
15
16pub type Headers = BTreeMap<String, String>;
17
18#[derive(Clone, PartialEq, Debug)]
19pub enum Method {
20    Describe,
21    Announce,
22    Setup,
23    Play,
24    Pause,
25    Record,
26    Options,
27    Redirect,
28    Teardown,
29    GetParameter,
30    SetParameter,
31}
32
33impl fmt::Display for Method {
34    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35        match self {
36            Method::Describe => write!(f, "DESCRIBE"),
37            Method::Announce => write!(f, "ANNOUNCE"),
38            Method::Setup => write!(f, "SETUP"),
39            Method::Play => write!(f, "PLAY"),
40            Method::Pause => write!(f, "PAUSE"),
41            Method::Record => write!(f, "RECORD"),
42            Method::Options => write!(f, "OPTIONS"),
43            Method::Redirect => write!(f, "REDIRECT"),
44            Method::Teardown => write!(f, "TEARDOWN"),
45            Method::GetParameter => write!(f, "GET_PARAMETER"),
46            Method::SetParameter => write!(f, "SET_PARAMETER"),
47        }
48    }
49}
50
51impl FromStr for Method {
52    type Err = Error;
53
54    fn from_str(s: &str) -> Result<Self, Self::Err> {
55        match s {
56            "DESCRIBE" => Ok(Method::Describe),
57            "ANNOUNCE" => Ok(Method::Announce),
58            "SETUP" => Ok(Method::Setup),
59            "PLAY" => Ok(Method::Play),
60            "PAUSE" => Ok(Method::Pause),
61            "RECORD" => Ok(Method::Record),
62            "OPTIONS" => Ok(Method::Options),
63            "REDIRECT" => Ok(Method::Redirect),
64            "TEARDOWN" => Ok(Method::Teardown),
65            "GET_PARAMETER" => Ok(Method::GetParameter),
66            "SET_PARAMETER" => Ok(Method::SetParameter),
67            _ => Err(Error::MethodUnknown {
68                method: s.to_string(),
69            }),
70        }
71    }
72}
73
74#[derive(Copy, Clone, PartialEq, Debug)]
75pub enum Version {
76    V1,
77    V2,
78    Unknown,
79}
80
81impl Default for Version {
82    #[inline]
83    fn default() -> Version {
84        Version::V1
85    }
86}
87
88impl fmt::Display for Version {
89    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
90        match self {
91            Version::V1 => write!(f, "1.0"),
92            Version::V2 => write!(f, "2.0"),
93            Version::Unknown => write!(f, "?"),
94        }
95    }
96}
97
98pub type StatusCode = usize;
99
100#[derive(Clone, PartialEq, Debug)]
101pub enum StatusCategory {
102    Informational,
103    Success,
104    Redirection,
105    ClientError,
106    ServerError,
107    Unknown,
108}
109
110#[derive(Clone, Copy, PartialEq, Debug)]
111pub enum Status {
112    Continue,
113    Ok,
114    Created,
115    LowonStorageSpace,
116    MultipleChoices,
117    MovedPermanently,
118    MovedTemporarily,
119    SeeOther,
120    UseProxy,
121    BadRequest,
122    Unauthorized,
123    PaymentRequired,
124    Forbidden,
125    NotFound,
126    MethodNotAllowed,
127    NotAcceptable,
128    ProxyAuthenticationRequired,
129    RequestTimeout,
130    Gone,
131    LengthRequired,
132    PreconditionFailed,
133    RequestEntityTooLarge,
134    RequestUriTooLong,
135    UnsupportedMediaType,
136    InvalidParameter,
137    IllegalConferenceIdentifier,
138    NotEnoughBandwidth,
139    SessionNotFound,
140    MethodNotValidInThisState,
141    HeaderFieldNotValid,
142    InvalidRange,
143    ParameterIsReadOnly,
144    AggregateOperationNotAllowed,
145    OnlyAggregateOperationAllowed,
146    UnsupportedTransport,
147    DestinationUnreachable,
148    InternalServerError,
149    NotImplemented,
150    BadGateway,
151    ServiceUnavailable,
152    GatewayTimeout,
153    RTSPVersionNotSupported,
154    OptionNotSupported,
155}
156
157pub(crate) fn status_to_code(status: Status) -> StatusCode {
158    match status {
159        Status::Continue => 100,
160        Status::Ok => 200,
161        Status::Created => 201,
162        Status::LowonStorageSpace => 250,
163        Status::MultipleChoices => 300,
164        Status::MovedPermanently => 301,
165        Status::MovedTemporarily => 302,
166        Status::SeeOther => 303,
167        Status::UseProxy => 305,
168        Status::BadRequest => 400,
169        Status::Unauthorized => 401,
170        Status::PaymentRequired => 402,
171        Status::Forbidden => 403,
172        Status::NotFound => 404,
173        Status::MethodNotAllowed => 405,
174        Status::NotAcceptable => 406,
175        Status::ProxyAuthenticationRequired => 407,
176        Status::RequestTimeout => 408,
177        Status::Gone => 410,
178        Status::LengthRequired => 411,
179        Status::PreconditionFailed => 412,
180        Status::RequestEntityTooLarge => 413,
181        Status::RequestUriTooLong => 414,
182        Status::UnsupportedMediaType => 415,
183        Status::InvalidParameter => 451,
184        Status::IllegalConferenceIdentifier => 452,
185        Status::NotEnoughBandwidth => 453,
186        Status::SessionNotFound => 454,
187        Status::MethodNotValidInThisState => 455,
188        Status::HeaderFieldNotValid => 456,
189        Status::InvalidRange => 457,
190        Status::ParameterIsReadOnly => 458,
191        Status::AggregateOperationNotAllowed => 459,
192        Status::OnlyAggregateOperationAllowed => 460,
193        Status::UnsupportedTransport => 461,
194        Status::DestinationUnreachable => 462,
195        Status::InternalServerError => 500,
196        Status::NotImplemented => 501,
197        Status::BadGateway => 502,
198        Status::ServiceUnavailable => 503,
199        Status::GatewayTimeout => 504,
200        Status::RTSPVersionNotSupported => 505,
201        Status::OptionNotSupported => 551,
202    }
203}
204
205pub(crate) fn status_to_reason(status: Status) -> &'static str {
206    match status {
207        Status::Continue => "Continue",
208        Status::Ok => "OK",
209        Status::Created => "Created",
210        Status::LowonStorageSpace => "Low on Storage Space",
211        Status::MultipleChoices => "Multiple Choices",
212        Status::MovedPermanently => "Moved Permanently",
213        Status::MovedTemporarily => "Moved Temporarily",
214        Status::SeeOther => "See Other",
215        Status::UseProxy => "Use Proxy",
216        Status::BadRequest => "Bad Request",
217        Status::Unauthorized => "Unauthorized",
218        Status::PaymentRequired => "Payment Required",
219        Status::Forbidden => "Forbidden",
220        Status::NotFound => "Not Found",
221        Status::MethodNotAllowed => "Method Not Allowed",
222        Status::NotAcceptable => "Not Acceptable",
223        Status::ProxyAuthenticationRequired => "Proxy Authentication Required",
224        Status::RequestTimeout => "Request Timeout",
225        Status::Gone => "Gone",
226        Status::LengthRequired => "Length Required",
227        Status::PreconditionFailed => "Precondition Failed",
228        Status::RequestEntityTooLarge => "Request Entity Too Large",
229        Status::RequestUriTooLong => "Request-URI Too Long",
230        Status::UnsupportedMediaType => "Unsupported Media Type",
231        Status::InvalidParameter => "Invalid parameter",
232        Status::IllegalConferenceIdentifier => "Illegal Conference Identifier",
233        Status::NotEnoughBandwidth => "Not Enough Bandwidth",
234        Status::SessionNotFound => "Session Not Found",
235        Status::MethodNotValidInThisState => "Method Not Valid In This State",
236        Status::HeaderFieldNotValid => "Header Field Not Valid",
237        Status::InvalidRange => "Invalid Range",
238        Status::ParameterIsReadOnly => "Parameter Is Read-Only",
239        Status::AggregateOperationNotAllowed => "Aggregate Operation Not Allowed",
240        Status::OnlyAggregateOperationAllowed => "Only Aggregate Operation Allowed",
241        Status::UnsupportedTransport => "Unsupported Transport",
242        Status::DestinationUnreachable => "Destination Unreachable",
243        Status::InternalServerError => "Internal Server Error",
244        Status::NotImplemented => "Not Implemented",
245        Status::BadGateway => "Bad Gateway",
246        Status::ServiceUnavailable => "Service Unavailable",
247        Status::GatewayTimeout => "Gateway Timeout",
248        Status::RTSPVersionNotSupported => "RTSP Version Not Supported",
249        Status::OptionNotSupported => "Option Not Supported",
250    }
251}