Skip to main content

dash_runtime/client/
meta.rs

1//! What the caller reports about a response beyond its body: the instants it
2//! measured on its own monotonic clock and the headers the client reads.
3
4/// An MPD response as the caller observed it.
5///
6/// `sent_us` and `received_us` are the caller's monotonic microseconds when
7/// the request left and when the first response byte arrived; the client
8/// places the server's `FetchTime` at their midpoint (23009-1 A.2). Every
9/// header is optional: a client with none of them still plays, it just
10/// refreshes unconditionally and has no `Date` clock fallback.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12#[non_exhaustive]
13pub struct ResponseMeta<'a> {
14    /// Monotonic microseconds when the request was sent.
15    pub sent_us: u64,
16    /// Monotonic microseconds when the first response byte arrived.
17    pub received_us: u64,
18    /// The `Date` header, verbatim.
19    pub date: Option<&'a str>,
20    /// The `ETag` header, verbatim.
21    pub etag: Option<&'a str>,
22    /// The `Last-Modified` header, verbatim.
23    pub last_modified: Option<&'a str>,
24    /// The URL the response came from after redirects, when it differs from
25    /// the URL requested.
26    pub final_url: Option<&'a str>,
27}
28
29impl<'a> ResponseMeta<'a> {
30    /// A response exchanged between `sent_us` and `received_us`, no headers.
31    #[must_use]
32    pub fn new(sent_us: u64, received_us: u64) -> Self {
33        Self {
34            sent_us,
35            received_us,
36            date: None,
37            etag: None,
38            last_modified: None,
39            final_url: None,
40        }
41    }
42
43    /// A response with no round trip of its own: sent and received at `now_us`.
44    #[must_use]
45    pub fn at(now_us: u64) -> Self {
46        Self::new(now_us, now_us)
47    }
48
49    /// Set the `Date` header.
50    #[must_use]
51    pub fn with_date(mut self, date: &'a str) -> Self {
52        self.date = Some(date);
53        self
54    }
55
56    /// Set the `ETag` header.
57    #[must_use]
58    pub fn with_etag(mut self, etag: &'a str) -> Self {
59        self.etag = Some(etag);
60        self
61    }
62
63    /// Set the `Last-Modified` header.
64    #[must_use]
65    pub fn with_last_modified(mut self, last_modified: &'a str) -> Self {
66        self.last_modified = Some(last_modified);
67        self
68    }
69
70    /// Set the post-redirect URL.
71    #[must_use]
72    pub fn with_final_url(mut self, final_url: &'a str) -> Self {
73        self.final_url = Some(final_url);
74        self
75    }
76}
77
78/// A `UTCTiming` response as the caller observed it.
79#[derive(Debug, Clone, Copy, PartialEq, Eq)]
80#[non_exhaustive]
81pub struct UtcResponse<'a> {
82    /// Monotonic microseconds when the request was sent.
83    pub sent_us: u64,
84    /// Monotonic microseconds when the first response byte arrived.
85    pub received_us: u64,
86    /// The `Date` header (the time of an `http-head` exchange).
87    pub date: Option<&'a str>,
88    /// The body, empty for a `HEAD`.
89    pub body: &'a [u8],
90}
91
92impl<'a> UtcResponse<'a> {
93    /// A response with a body and no `Date`.
94    #[must_use]
95    pub fn new(sent_us: u64, received_us: u64, body: &'a [u8]) -> Self {
96        Self {
97            sent_us,
98            received_us,
99            date: None,
100            body,
101        }
102    }
103
104    /// Set the `Date` header.
105    #[must_use]
106    pub fn with_date(mut self, date: &'a str) -> Self {
107        self.date = Some(date);
108        self
109    }
110}