rtsp_types/
message.rs

1// Copyright (C) 2020 Sebastian Dröge <sebastian@centricular.com>
2//
3// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
4
5use super::*;
6
7use crate::headers::{TypedAppendableHeader, TypedHeader};
8
9/// Enum holding all possible RTSP message types.
10///
11/// A `Message` can be a [`Request`](struct.Request.html), a [`Response`](struct.Response.html) or
12/// [`Data`](struct.Data.html).
13///
14/// The body of the message is generic and usually a type that implements `AsRef<[u8]>`. For empty
15/// bodies there also exists the [`Empty`](struct.Empty.html) type.
16#[derive(Debug, PartialEq, Eq, Clone)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18pub enum Message<Body> {
19    /// Request message
20    Request(Request<Body>),
21    /// Response message
22    Response(Response<Body>),
23    /// Data message
24    Data(Data<Body>),
25}
26
27impl<Body> From<Request<Body>> for Message<Body> {
28    fn from(v: Request<Body>) -> Self {
29        Message::Request(v)
30    }
31}
32
33impl<Body> From<Response<Body>> for Message<Body> {
34    fn from(v: Response<Body>) -> Self {
35        Message::Response(v)
36    }
37}
38
39impl<Body> From<Data<Body>> for Message<Body> {
40    fn from(v: Data<Body>) -> Self {
41        Message::Data(v)
42    }
43}
44
45impl<Body: AsRef<[u8]>> Message<Body> {
46    pub(crate) fn borrow(&self) -> MessageRef {
47        match self {
48            Message::Request(request) => MessageRef::Request(request.borrow()),
49            Message::Response(response) => MessageRef::Response(response.borrow()),
50            Message::Data(data) => MessageRef::Data(data.borrow()),
51        }
52    }
53
54    /// Serialize the message to any `std::io::Write`.
55    ///
56    /// Resuming writing after `std::io::ErrorKind::WouldBlock` is not supported. Any previously
57    /// written data will have to be discarded for resuming.
58    ///
59    /// ## Serializing an RTSP message
60    ///
61    /// ```rust
62    /// let request = rtsp_types::Request::builder(
63    ///         rtsp_types::Method::SetParameter,
64    ///         rtsp_types::Version::V2_0
65    ///     )
66    ///     .request_uri(rtsp_types::Url::parse("rtsp://example.com/test").expect("Invalid URI"))
67    ///     .header(rtsp_types::headers::CSEQ, "2")
68    ///     .header(rtsp_types::headers::CONTENT_TYPE, "text/parameters")
69    ///     .build(Vec::from(&b"barparam: barstuff"[..]));
70    ///
71    ///  let mut data = Vec::new();
72    ///  request.write(&mut data).expect("Failed to serialize request");
73    ///
74    ///  assert_eq!(
75    ///     data,
76    ///     b"SET_PARAMETER rtsp://example.com/test RTSP/2.0\r\n\
77    ///       Content-Length: 18\r\n\
78    ///       Content-Type: text/parameters\r\n\
79    ///       CSeq: 2\r\n\
80    ///       \r\n\
81    ///       barparam: barstuff",
82    ///  );
83    /// ```
84    pub fn write<'b, W: std::io::Write + 'b>(&self, w: &'b mut W) -> Result<(), WriteError> {
85        self.borrow().write(w)
86    }
87
88    /// Calculate the number of bytes needed to serialize the message.
89    pub fn write_len(&self) -> u64 {
90        self.borrow().write_len()
91    }
92}
93
94impl<'a, T: From<&'a [u8]>> Message<T> {
95    /// Try parse a message from a `&[u8]` and also return how many bytes were consumed.
96    ///
97    /// The body type of the returned message can be any type that implements `From<&[u8]>`. This
98    /// includes `Vec<u8>` and `&[u8]` among others.
99    ///
100    /// If parsing the message succeeds, in addition to the message itself also the number of bytes
101    /// that were consumed from the input data are returned. This allows the caller to advance to
102    /// the next message.
103    ///
104    /// If parsing the message fails with [`ParseError::Incomplete`](enum.ParseError.html#variant.Incomplete)
105    /// then the caller has to provide more data for successfully parsing the message.
106    ///
107    /// Otherwise, if parsing the message fails with [`ParseError::Error`](enum.ParseError.html#variant.Error)
108    /// then the message can't be parsed and the caller can try skipping over some data until
109    /// parsing succeeds again.
110    ///
111    /// ## Parsing an RTSP message
112    ///
113    /// ```rust
114    /// let data = b"OPTIONS * RTSP/2.0\r\n\
115    ///              CSeq: 1\r\n\
116    ///              Supported: play.basic, play.scale\r\n\
117    ///              User-Agent: PhonyClient/1.2\r\n\
118    ///              \r\n";
119    ///
120    /// let (message, consumed): (rtsp_types::Message<Vec<u8>>, _) =
121    ///     rtsp_types::Message::parse(data).expect("Failed to parse data");
122    ///
123    /// assert_eq!(consumed, data.len());
124    /// match message {
125    ///     rtsp_types::Message::Request(ref request) => {
126    ///         assert_eq!(request.method(), rtsp_types::Method::Options);
127    ///     },
128    ///     _ => unreachable!(),
129    /// }
130    /// ```
131    pub fn parse<B: AsRef<[u8]> + 'a + ?Sized>(buf: &'a B) -> Result<(Self, usize), ParseError> {
132        let buf = buf.as_ref();
133        let (msg, consumed) = MessageRef::parse(buf)?;
134
135        Ok((msg.to_owned()?, consumed))
136    }
137}
138
139/// RTSP method.
140///
141/// See [RFC 7826 section 13](https://tools.ietf.org/html/rfc7826#section-13) for the details about
142/// each method.
143#[derive(Debug, PartialEq, Eq, Clone)]
144#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
145pub enum Method {
146    /// Describe
147    Describe,
148    /// Get parameter
149    GetParameter,
150    /// Options
151    Options,
152    /// Pause
153    Pause,
154    /// Play
155    Play,
156    /// Play notify (only RTSP 2.0)
157    PlayNotify,
158    /// Redirect
159    Redirect,
160    /// Setup
161    Setup,
162    /// Set parameter
163    SetParameter,
164    /// Announce (only RTSP 1.0)
165    Announce,
166    /// Record (only RTSP 1.0)
167    Record,
168    /// Teardown
169    Teardown,
170    /// Extension method
171    Extension(String),
172}
173
174impl Method {
175    pub(crate) fn borrow(&self) -> MethodRef {
176        match self {
177            Method::Describe => MethodRef::Describe,
178            Method::GetParameter => MethodRef::GetParameter,
179            Method::Options => MethodRef::Options,
180            Method::Pause => MethodRef::Pause,
181            Method::Play => MethodRef::Play,
182            Method::PlayNotify => MethodRef::PlayNotify,
183            Method::Redirect => MethodRef::Redirect,
184            Method::Setup => MethodRef::Setup,
185            Method::SetParameter => MethodRef::SetParameter,
186            Method::Announce => MethodRef::Announce,
187            Method::Record => MethodRef::Record,
188            Method::Teardown => MethodRef::Teardown,
189            Method::Extension(s) => MethodRef::Extension(s),
190        }
191    }
192}
193
194/// Parses a method from a `&str`.
195impl<'a> From<&'a str> for Method {
196    fn from(v: &'a str) -> Self {
197        MethodRef::from(v).to_owned()
198    }
199}
200
201/// Converts a method into a `&str`.
202impl<'a> From<&'a Method> for &'a str {
203    fn from(v: &'a Method) -> Self {
204        match v {
205            Method::Describe => "DESCRIBE",
206            Method::GetParameter => "GET_PARAMETER",
207            Method::Options => "OPTIONS",
208            Method::Pause => "PAUSE",
209            Method::Play => "PLAY",
210            Method::PlayNotify => "PLAY_NOTIFY",
211            Method::Redirect => "REDIRECT",
212            Method::Setup => "SETUP",
213            Method::SetParameter => "SET_PARAMETER",
214            Method::Announce => "ANNOUNCE",
215            Method::Record => "RECORD",
216            Method::Teardown => "TEARDOWN",
217            Method::Extension(ref v) => v,
218        }
219    }
220}
221
222impl PartialEq<Method> for &Method {
223    fn eq(&self, other: &Method) -> bool {
224        (*self).eq(other)
225    }
226}
227
228/// RTSP Request.
229///
230/// Represents an RTSP request and providers functions to construct, modify and read requests.
231///
232/// See [RFC 7826 section 7](https://tools.ietf.org/html/rfc7826#section-7) for the details about
233/// methods.
234///
235/// ## Creating an `OPTIONS` request
236///
237/// ```rust
238/// let request = rtsp_types::Request::builder(
239///         rtsp_types::Method::Options,
240///         rtsp_types::Version::V2_0
241///     )
242///     .header(rtsp_types::headers::CSEQ, "1")
243///     .empty();
244/// ```
245///
246/// This request contains an empty body.
247///
248/// ## Creating a `SET_PARAMETER` request with a request body
249///
250/// ```rust
251/// let request = rtsp_types::Request::builder(
252///         rtsp_types::Method::SetParameter,
253///         rtsp_types::Version::V2_0
254///     )
255///     .request_uri(rtsp_types::Url::parse("rtsp://example.com/test").expect("Invalid URI"))
256///     .header(rtsp_types::headers::CSEQ, "2")
257///     .header(rtsp_types::headers::CONTENT_TYPE, "text/parameters")
258///     .build(Vec::from(&b"barparam: barstuff"[..]));
259/// ```
260#[derive(Debug, Clone, Eq)]
261#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
262pub struct Request<Body> {
263    pub(crate) method: Method,
264    pub(crate) request_uri: Option<Url>,
265    pub(crate) version: Version,
266    pub(crate) headers: Headers,
267    pub(crate) body: Body,
268}
269
270impl<BodyA, BodyB: PartialEq<BodyA>> PartialEq<Request<BodyA>> for Request<BodyB> {
271    fn eq(&self, other: &Request<BodyA>) -> bool {
272        self.method == other.method
273            && self.request_uri == other.request_uri
274            && self.version == other.version
275            && self.headers == other.headers
276            && self.body == other.body
277    }
278}
279
280impl Request<Empty> {
281    /// Build a new `Request` for a given method and RTSP version.
282    pub fn builder(method: Method, version: Version) -> RequestBuilder {
283        RequestBuilder::new(method, version)
284    }
285}
286
287impl<Body> Request<Body> {
288    pub(crate) fn borrow(&self) -> RequestRef
289    where
290        Body: AsRef<[u8]>,
291    {
292        let headers = self
293            .headers
294            .iter()
295            .map(|(name, value)| HeaderRef {
296                name: name.as_str(),
297                value: value.as_str(),
298            })
299            .collect();
300
301        RequestRef {
302            method: self.method.borrow(),
303            request_uri: self.request_uri.as_ref().map(|u| u.as_str()),
304            version: self.version,
305            headers,
306            body: self.body.as_ref(),
307        }
308    }
309
310    /// Serialize the request to any `std::io::Write`.
311    ///
312    /// Resuming writing after `std::io::ErrorKind::WouldBlock` is not supported. Any previously
313    /// written data will have to be discarded for resuming.
314    pub fn write<'b, W: std::io::Write + 'b>(&self, w: &'b mut W) -> Result<(), WriteError>
315    where
316        Body: AsRef<[u8]>,
317    {
318        self.borrow().write(w)
319    }
320
321    /// Calculate the number of bytes needed to serialize the request.
322    pub fn write_len(&self) -> u64
323    where
324        Body: AsRef<[u8]>,
325    {
326        self.borrow().write_len()
327    }
328
329    // Accessors
330    /// Get the method of the request.
331    pub fn method(&self) -> &Method {
332        &self.method
333    }
334
335    /// Set the method of the request.
336    pub fn set_method(&mut self, method: Method) {
337        self.method = method;
338    }
339
340    /// Get the request URI of the request.
341    pub fn request_uri(&self) -> Option<&Url> {
342        self.request_uri.as_ref()
343    }
344
345    /// Set the request URI of the request.
346    pub fn set_request_uri(&mut self, request_uri: Option<Url>) {
347        self.request_uri = request_uri;
348    }
349
350    /// Get the version of the request.
351    pub fn version(&self) -> Version {
352        self.version
353    }
354
355    /// Set the version of the request.
356    pub fn set_version(&mut self, version: Version) {
357        self.version = version;
358    }
359
360    /// Get the body of the request.
361    pub fn body(&self) -> &Body {
362        &self.body
363    }
364
365    // Body API
366    /// Convert the request into its body.
367    pub fn into_body(self) -> Body {
368        self.body
369    }
370
371    /// Modify the body of the request with a closure.
372    ///
373    /// This replaces the `Content-Length` header of the message with the length of the new body.
374    pub fn map_body<NewBody: AsRef<[u8]>, F: FnOnce(Body) -> NewBody>(
375        self,
376        func: F,
377    ) -> Request<NewBody> {
378        let Request {
379            method,
380            request_uri,
381            version,
382            mut headers,
383            body,
384        } = self;
385
386        let new_body = func(body);
387
388        {
389            let new_body = new_body.as_ref();
390            if new_body.is_empty() {
391                headers.remove(&crate::headers::CONTENT_LENGTH);
392            } else {
393                headers.insert(
394                    crate::headers::CONTENT_LENGTH,
395                    HeaderValue::from(format!("{}", new_body.len())),
396                );
397            }
398        }
399
400        Request {
401            method,
402            request_uri,
403            version,
404            headers,
405            body: new_body,
406        }
407    }
408
409    /// Replace the body of the request with a different body.
410    ///
411    /// This replaces the `Content-Length` header of the message with the length of the new body.
412    pub fn replace_body<NewBody: AsRef<[u8]>>(self, new_body: NewBody) -> Request<NewBody> {
413        let Request {
414            method,
415            request_uri,
416            version,
417            mut headers,
418            body: _body,
419        } = self;
420
421        {
422            let new_body = new_body.as_ref();
423            if new_body.is_empty() {
424                headers.remove(&crate::headers::CONTENT_LENGTH);
425            } else {
426                headers.insert(
427                    crate::headers::CONTENT_LENGTH,
428                    HeaderValue::from(format!("{}", new_body.len())),
429                );
430            }
431        }
432
433        Request {
434            method,
435            request_uri,
436            version,
437            headers,
438            body: new_body,
439        }
440    }
441
442    // Header API
443    /// Appends a value to an existing RTSP header or inserts it.
444    ///
445    /// Additional values are comma separated as defined in [RFC 7826 section 5.2](https://tools.ietf.org/html/rfc7826#section-5.2).
446    pub fn append_header<V: Into<HeaderValue>>(&mut self, name: HeaderName, value: V) {
447        let value = value.into();
448        self.headers.append(name, value);
449    }
450
451    /// Insert an RTSP header with its value.
452    ///
453    /// If a header with the same name already exists then its value will be replaced.
454    ///
455    /// See [`append`](#method.append) for appending additional values to a header.
456    pub fn insert_header<V: Into<HeaderValue>>(&mut self, name: HeaderName, value: V) {
457        let value = value.into();
458        self.headers.insert(name, value);
459    }
460
461    /// Append a typed RTSP header with its value.
462    pub fn append_typed_header<H: TypedAppendableHeader>(&mut self, header: &H) {
463        self.headers.append_typed(header);
464    }
465
466    /// Insert a typed RTSP header with its value.
467    ///
468    /// If a header with the same name already exists then its value will be replaced.
469    pub fn insert_typed_header<H: TypedHeader>(&mut self, header: &H) {
470        self.headers.insert_typed(header);
471    }
472
473    /// Removes and RTSP header if it exists.
474    pub fn remove_header(&mut self, name: &HeaderName) {
475        self.headers.remove(name);
476    }
477
478    /// Gets an RTSP header value if it exists.
479    pub fn header(&self, name: &HeaderName) -> Option<&HeaderValue> {
480        self.headers.get(name)
481    }
482
483    /// Gets a typed RTSP header value if it exists.
484    pub fn typed_header<H: TypedHeader>(&self) -> Result<Option<H>, headers::HeaderParseError> {
485        self.headers.get_typed()
486    }
487
488    /// Gets a mutable reference to an RTSP header value if it exists.
489    pub fn header_mut(&mut self, name: &HeaderName) -> Option<&mut HeaderValue> {
490        self.headers.get_mut(name)
491    }
492
493    /// Iterator over all header name and value pairs.
494    pub fn headers(&self) -> impl Iterator<Item = (&HeaderName, &HeaderValue)> {
495        self.headers.iter()
496    }
497
498    /// Iterator over all header names.
499    pub fn header_names(&self) -> impl Iterator<Item = &HeaderName> {
500        self.headers.names()
501    }
502
503    /// Iterator over all header values.
504    pub fn header_values(&self) -> impl Iterator<Item = &HeaderValue> {
505        self.headers.values()
506    }
507}
508
509impl<Body> AsRef<Headers> for Request<Body> {
510    fn as_ref(&self) -> &Headers {
511        &self.headers
512    }
513}
514
515impl<Body> AsMut<Headers> for Request<Body> {
516    fn as_mut(&mut self) -> &mut Headers {
517        &mut self.headers
518    }
519}
520
521/// RTSP request builder.
522///
523/// See [`Request::builder`](struct.Request.html#method.builder) for details.
524#[derive(Debug, PartialEq, Eq, Clone)]
525pub struct RequestBuilder(Request<Empty>);
526
527impl RequestBuilder {
528    fn new(method: Method, version: Version) -> Self {
529        Self(Request {
530            method,
531            request_uri: None,
532            version,
533            headers: Headers::new(),
534            body: Empty,
535        })
536    }
537
538    /// Set the optional request URI.
539    pub fn request_uri<U: Into<Url>>(self, request_uri: U) -> Self {
540        Self(Request {
541            request_uri: Some(request_uri.into()),
542            ..self.0
543        })
544    }
545
546    /// Append a header to the request.
547    pub fn header<V: Into<HeaderValue>>(mut self, name: HeaderName, value: V) -> Self {
548        let value = value.into();
549
550        self.0.headers.append(name, value);
551
552        self
553    }
554
555    /// Append a typed header to the request.
556    pub fn typed_header<H: TypedHeader>(mut self, header: &H) -> Self {
557        self.0.headers.insert_typed(header);
558
559        self
560    }
561
562    /// Build a request with an empty body.
563    pub fn empty(self) -> Request<Empty> {
564        self.0
565    }
566
567    /// Build a request with a provided body.
568    ///
569    /// This inserts the `Content-Length` header with the length of the body if it is not empty.
570    pub fn build<Body: AsRef<[u8]>>(mut self, body: Body) -> Request<Body> {
571        {
572            let body = body.as_ref();
573            if !body.is_empty() {
574                self.0.headers.insert(
575                    crate::headers::CONTENT_LENGTH,
576                    HeaderValue::from(format!("{}", body.len())),
577                );
578            }
579        }
580
581        Request {
582            method: self.0.method,
583            request_uri: self.0.request_uri,
584            version: self.0.version,
585            headers: self.0.headers,
586            body,
587        }
588    }
589}
590
591/// RTSP Response.
592///
593/// Represents an RTSP response and providers functions to construct, modify and read responses.
594///
595/// See [RFC 7826 section 8](https://tools.ietf.org/html/rfc7826#section-8) for the details about
596/// methods.
597///
598/// ## Creating an `OK` response
599///
600/// ```rust
601/// let response = rtsp_types::Response::builder(
602///         rtsp_types::Version::V2_0,
603///         rtsp_types::StatusCode::Ok,
604///     )
605///     .header(rtsp_types::headers::CSEQ, "1")
606///     .empty();
607/// ```
608#[derive(Debug, Clone, Eq)]
609#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
610pub struct Response<Body> {
611    pub(crate) version: Version,
612    pub(crate) status: StatusCode,
613    pub(crate) reason_phrase: String,
614    pub(crate) headers: Headers,
615    pub(crate) body: Body,
616}
617
618impl<BodyA, BodyB: PartialEq<BodyA>> PartialEq<Response<BodyA>> for Response<BodyB> {
619    fn eq(&self, other: &Response<BodyA>) -> bool {
620        self.version == other.version
621            && self.status == other.status
622            && self.reason_phrase == other.reason_phrase
623            && self.headers == other.headers
624            && self.body == other.body
625    }
626}
627
628impl Response<Empty> {
629    /// Build a new `Response` for a given RTSP version and status code.
630    pub fn builder(version: Version, status: StatusCode) -> ResponseBuilder {
631        ResponseBuilder::new(version, status)
632    }
633}
634
635impl<Body> Response<Body> {
636    pub(crate) fn borrow(&self) -> ResponseRef
637    where
638        Body: AsRef<[u8]>,
639    {
640        let headers = self
641            .headers
642            .iter()
643            .map(|(name, value)| HeaderRef {
644                name: name.as_str(),
645                value: value.as_str(),
646            })
647            .collect();
648
649        ResponseRef {
650            version: self.version,
651            status: self.status,
652            reason_phrase: &self.reason_phrase,
653            headers,
654            body: self.body.as_ref(),
655        }
656    }
657
658    /// Serialize the response to any `std::io::Write`.
659    ///
660    /// Resuming writing after `std::io::ErrorKind::WouldBlock` is not supported. Any previously
661    /// written data will have to be discarded for resuming.
662    pub fn write<'b, W: std::io::Write + 'b>(&self, w: &'b mut W) -> Result<(), WriteError>
663    where
664        Body: AsRef<[u8]>,
665    {
666        self.borrow().write(w)
667    }
668
669    /// Calculate the number of bytes needed to serialize the response.
670    pub fn write_len(&self) -> u64
671    where
672        Body: AsRef<[u8]>,
673    {
674        self.borrow().write_len()
675    }
676
677    // Accessors
678    /// Get the version of the response.
679    pub fn version(&self) -> Version {
680        self.version
681    }
682
683    /// Set the version of the response.
684    pub fn set_version(&mut self, version: Version) {
685        self.version = version;
686    }
687
688    /// Get the status code of the response.
689    pub fn status(&self) -> StatusCode {
690        self.status
691    }
692
693    /// Set the status code of the response.
694    pub fn set_status(&mut self, status: StatusCode) {
695        self.status = status;
696    }
697
698    /// Get the reason phrase of the response.
699    pub fn reason_phrase(&self) -> &str {
700        self.reason_phrase.as_str()
701    }
702
703    /// Set the reason phrase of the response.
704    pub fn set_reason_phrase<S: Into<String>>(&mut self, reason_phrase: S) {
705        self.reason_phrase = reason_phrase.into();
706    }
707
708    /// Get the body of the response.
709    pub fn body(&self) -> &Body {
710        &self.body
711    }
712
713    // Body API
714    /// Convert the response into its body.
715    pub fn into_body(self) -> Body {
716        self.body
717    }
718
719    /// Modify the body of the response with a closure.
720    ///
721    /// This replaces the `Content-Length` header of the message with the length of the new body.
722    pub fn map_body<NewBody: AsRef<[u8]>, F: FnOnce(Body) -> NewBody>(
723        self,
724        func: F,
725    ) -> Response<NewBody> {
726        let Response {
727            version,
728            status,
729            reason_phrase,
730            mut headers,
731            body,
732        } = self;
733
734        let new_body = func(body);
735
736        {
737            let new_body = new_body.as_ref();
738            if new_body.is_empty() {
739                headers.remove(&crate::headers::CONTENT_LENGTH);
740            } else {
741                headers.insert(
742                    crate::headers::CONTENT_LENGTH,
743                    HeaderValue::from(format!("{}", new_body.len())),
744                );
745            }
746        }
747
748        Response {
749            version,
750            status,
751            reason_phrase,
752            headers,
753            body: new_body,
754        }
755    }
756
757    /// Replace the body of the response with a different body.
758    ///
759    /// This replaces the `Content-Length` header of the message with the length of the new body.
760    pub fn replace_body<NewBody: AsRef<[u8]>>(self, new_body: NewBody) -> Response<NewBody> {
761        let Response {
762            version,
763            status,
764            reason_phrase,
765            mut headers,
766            body: _body,
767        } = self;
768
769        {
770            let new_body = new_body.as_ref();
771            if new_body.is_empty() {
772                headers.remove(&crate::headers::CONTENT_LENGTH);
773            } else {
774                headers.insert(
775                    crate::headers::CONTENT_LENGTH,
776                    HeaderValue::from(format!("{}", new_body.len())),
777                );
778            }
779        }
780
781        Response {
782            version,
783            status,
784            reason_phrase,
785            headers,
786            body: new_body,
787        }
788    }
789
790    // Header API
791    /// Appends a value to an existing RTSP header or inserts it.
792    ///
793    /// Additional values are comma separated as defined in [RFC 7826 section 5.2](https://tools.ietf.org/html/rfc7826#section-5.2).
794    pub fn append_header<V: Into<HeaderValue>>(&mut self, name: HeaderName, value: V) {
795        let value = value.into();
796        self.headers.append(name, value);
797    }
798
799    /// Insert an RTSP header with its value.
800    ///
801    /// If a header with the same name already exists then its value will be replaced.
802    ///
803    /// See [`append`](#method.append) for appending additional values to a header.
804    pub fn insert_header<V: Into<HeaderValue>>(&mut self, name: HeaderName, value: V) {
805        let value = value.into();
806        self.headers.insert(name, value);
807    }
808
809    /// Append a typed RTSP header with its value.
810    pub fn append_typed_header<H: TypedAppendableHeader>(&mut self, header: &H) {
811        self.headers.append_typed(header);
812    }
813
814    /// Insert a typed RTSP header with its value.
815    ///
816    /// If a header with the same name already exists then its value will be replaced.
817    pub fn insert_typed_header<H: TypedHeader>(&mut self, header: &H) {
818        self.headers.insert_typed(header);
819    }
820
821    /// Removes and RTSP header if it exists.
822    pub fn remove_header(&mut self, name: &HeaderName) {
823        self.headers.remove(name);
824    }
825
826    /// Gets an RTSP header value if it exists.
827    pub fn header(&self, name: &HeaderName) -> Option<&HeaderValue> {
828        self.headers.get(name)
829    }
830
831    /// Gets a typed RTSP header value if it exists.
832    pub fn typed_header<H: TypedHeader>(&self) -> Result<Option<H>, headers::HeaderParseError> {
833        self.headers.get_typed()
834    }
835
836    /// Gets a mutable reference to an RTSP header value if it exists.
837    pub fn header_mut(&mut self, name: &HeaderName) -> Option<&mut HeaderValue> {
838        self.headers.get_mut(name)
839    }
840
841    /// Iterator over all header name and value pairs.
842    pub fn headers(&self) -> impl Iterator<Item = (&HeaderName, &HeaderValue)> {
843        self.headers.iter()
844    }
845
846    /// Iterator over all header names.
847    pub fn header_names(&self) -> impl Iterator<Item = &HeaderName> {
848        self.headers.names()
849    }
850
851    /// Iterator over all header values.
852    pub fn header_values(&self) -> impl Iterator<Item = &HeaderValue> {
853        self.headers.values()
854    }
855}
856
857impl<Body> AsRef<Headers> for Response<Body> {
858    fn as_ref(&self) -> &Headers {
859        &self.headers
860    }
861}
862
863impl<Body> AsMut<Headers> for Response<Body> {
864    fn as_mut(&mut self) -> &mut Headers {
865        &mut self.headers
866    }
867}
868
869/// RTSP response builder.
870///
871/// See [`Response::builder`](struct.Response.html#method.builder) for details.
872#[derive(Debug, PartialEq, Eq, Clone)]
873pub struct ResponseBuilder(Response<Empty>, Option<String>);
874
875impl ResponseBuilder {
876    fn new(version: Version, status: StatusCode) -> Self {
877        let response = Response {
878            version,
879            status,
880            reason_phrase: String::new(),
881            headers: Headers::new(),
882            body: Empty,
883        };
884
885        Self(response, None)
886    }
887
888    /// Set the reason phrase of the response.
889    ///
890    /// If not set then a default reason phrase will be used based on the status code.
891    pub fn reason_phrase<S: Into<String>>(mut self, reason_phrase: S) -> Self {
892        let reason_phrase = reason_phrase.into();
893
894        self.1 = Some(reason_phrase);
895
896        self
897    }
898
899    /// Append a header to the response.
900    pub fn header<V: Into<HeaderValue>>(mut self, name: HeaderName, value: V) -> Self {
901        let value = value.into();
902
903        self.0.headers.append(name, value);
904
905        self
906    }
907
908    /// Append a typed header to the response.
909    pub fn typed_header<H: TypedHeader>(mut self, header: &H) -> Self {
910        self.0.headers.insert_typed(header);
911
912        self
913    }
914
915    /// Build a response with an empty body.
916    pub fn empty(self) -> Response<Empty> {
917        let ResponseBuilder(mut response, reason_phrase) = self;
918
919        response.reason_phrase = reason_phrase.unwrap_or_else(|| response.status.to_string());
920
921        response
922    }
923
924    /// Build a response with a provided body.
925    ///
926    /// This inserts the `Content-Length` header with the length of the body if it is not empty.
927    pub fn build<Body: AsRef<[u8]>>(self, body: Body) -> Response<Body> {
928        let ResponseBuilder(mut response, reason_phrase) = self;
929
930        {
931            let body = body.as_ref();
932            if !body.is_empty() {
933                response.headers.insert(
934                    crate::headers::CONTENT_LENGTH,
935                    HeaderValue::from(format!("{}", body.len())),
936                );
937            }
938        }
939
940        let reason_phrase = reason_phrase.unwrap_or_else(|| response.status.to_string());
941
942        Response {
943            version: response.version,
944            status: response.status,
945            reason_phrase,
946            headers: response.headers,
947            body,
948        }
949    }
950}
951
952/// RTSP data message.
953///
954/// See [RFC 7826 section 14](https://tools.ietf.org/html/rfc7826#section-14) for details about the
955/// data message.
956#[derive(Debug, Clone, Eq)]
957#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
958pub struct Data<Body> {
959    pub(crate) channel_id: u8,
960    pub(crate) body: Body,
961}
962
963impl<BodyA, BodyB: PartialEq<BodyA>> PartialEq<Data<BodyA>> for Data<BodyB> {
964    fn eq(&self, other: &Data<BodyA>) -> bool {
965        self.channel_id == other.channel_id && self.body == other.body
966    }
967}
968
969impl<Body> Data<Body> {
970    pub(crate) fn borrow(&self) -> DataRef
971    where
972        Body: AsRef<[u8]>,
973    {
974        DataRef {
975            channel_id: self.channel_id,
976            body: self.body.as_ref(),
977        }
978    }
979
980    /// Create a new data message for a given channel id and body.
981    pub fn new(channel_id: u8, body: Body) -> Self {
982        Self { channel_id, body }
983    }
984
985    /// Serialize the data to any `std::io::Write`.
986    ///
987    /// Resuming writing after `std::io::ErrorKind::WouldBlock` is not supported. Any previously
988    /// written data will have to be discarded for resuming.
989    pub fn write<'b, W: std::io::Write + 'b>(&self, w: &'b mut W) -> Result<(), WriteError>
990    where
991        Body: AsRef<[u8]>,
992    {
993        self.borrow().write(w)
994    }
995
996    /// Calculate the number of bytes needed to serialize the data.
997    pub fn write_len(&self) -> u64
998    where
999        Body: AsRef<[u8]>,
1000    {
1001        self.borrow().write_len()
1002    }
1003
1004    // Accessors
1005    /// Get the channel id of the data message.
1006    pub fn channel_id(&self) -> u8 {
1007        self.channel_id
1008    }
1009
1010    /// Set the channel id of the data message.
1011    pub fn set_channel_id(&mut self, channel_id: u8) {
1012        self.channel_id = channel_id;
1013    }
1014
1015    /// Get the length of the data message.
1016    pub fn len(&self) -> usize
1017    where
1018        Body: AsRef<[u8]>,
1019    {
1020        self.body.as_ref().len()
1021    }
1022
1023    /// Check if the body of the data message is empty.
1024    pub fn is_empty(&self) -> bool
1025    where
1026        Body: AsRef<[u8]>,
1027    {
1028        self.body.as_ref().is_empty()
1029    }
1030
1031    /// Get a `&[u8]` slice for the body of the data message.
1032    pub fn as_slice(&self) -> &[u8]
1033    where
1034        Body: AsRef<[u8]>,
1035    {
1036        self.body.as_ref()
1037    }
1038
1039    // Body API
1040    /// Convert the data message into its body.
1041    pub fn into_body(self) -> Body {
1042        self.body
1043    }
1044
1045    /// Modify the body of the data message with a closure.
1046    pub fn map_body<NewBody, F: FnOnce(Body) -> NewBody>(self, func: F) -> Data<NewBody> {
1047        Data {
1048            channel_id: self.channel_id,
1049            body: func(self.body),
1050        }
1051    }
1052
1053    /// Replace the body of the data message with a different body.
1054    pub fn replace_body<NewBody>(self, new_body: NewBody) -> Data<NewBody> {
1055        Data {
1056            channel_id: self.channel_id,
1057            body: new_body,
1058        }
1059    }
1060}
1061
1062impl Data<Vec<u8>> {
1063    /// Create a new data message from a `Vec<u8>`.
1064    pub fn from_vec(channel_id: u8, body: Vec<u8>) -> Self {
1065        Self { channel_id, body }
1066    }
1067}
1068
1069impl<Body: AsRef<[u8]>> AsRef<[u8]> for Data<Body> {
1070    fn as_ref(&self) -> &[u8] {
1071        self.body.as_ref()
1072    }
1073}