halldyll_core/fetch/
request.rs

1//! Request - HTTP request building
2
3use reqwest::header::{HeaderMap, HeaderName, HeaderValue, ACCEPT, ACCEPT_ENCODING, ACCEPT_LANGUAGE, IF_MODIFIED_SINCE, IF_NONE_MATCH};
4use url::Url;
5
6use crate::types::Config;
7
8/// HTTP request builder
9pub struct RequestBuilder {
10    url: Url,
11    headers: HeaderMap,
12    etag: Option<String>,
13    last_modified: Option<String>,
14}
15
16impl RequestBuilder {
17    /// New request for a URL
18    pub fn new(url: Url) -> Self {
19        Self {
20            url,
21            headers: HeaderMap::new(),
22            etag: None,
23            last_modified: None,
24        }
25    }
26
27    /// Apply default configuration
28    pub fn with_config(mut self, config: &Config) -> Self {
29        // Accept headers
30        if let Ok(v) = HeaderValue::from_str(&config.fetch.accept_headers.accept) {
31            self.headers.insert(ACCEPT, v);
32        }
33        if let Ok(v) = HeaderValue::from_str(&config.fetch.accept_headers.accept_language) {
34            self.headers.insert(ACCEPT_LANGUAGE, v);
35        }
36        if let Ok(v) = HeaderValue::from_str(&config.fetch.accept_headers.accept_encoding) {
37            self.headers.insert(ACCEPT_ENCODING, v);
38        }
39        self
40    }
41
42    /// Add a custom header
43    pub fn header(mut self, name: &str, value: &str) -> Self {
44        if let (Ok(n), Ok(v)) = (
45            HeaderName::try_from(name),
46            HeaderValue::from_str(value),
47        ) {
48            self.headers.insert(n, v);
49        }
50        self
51    }
52
53    /// Configure conditional request with ETag
54    pub fn if_none_match(mut self, etag: &str) -> Self {
55        self.etag = Some(etag.to_string());
56        if let Ok(v) = HeaderValue::from_str(etag) {
57            self.headers.insert(IF_NONE_MATCH, v);
58        }
59        self
60    }
61
62    /// Configure conditional request with Last-Modified
63    pub fn if_modified_since(mut self, date: &str) -> Self {
64        self.last_modified = Some(date.to_string());
65        if let Ok(v) = HeaderValue::from_str(date) {
66            self.headers.insert(IF_MODIFIED_SINCE, v);
67        }
68        self
69    }
70
71    /// Returns the URL
72    pub fn url(&self) -> &Url {
73        &self.url
74    }
75
76    /// Returns the headers
77    pub fn headers(&self) -> &HeaderMap {
78        &self.headers
79    }
80
81    /// Consume and return components
82    pub fn build(self) -> (Url, HeaderMap) {
83        (self.url, self.headers)
84    }
85}