http_client.rs

  1//! An HTTP client.
  2
  3pub use crate::wit::zed::extension::http_client::{
  4    HttpMethod, HttpRequest, HttpResponse, HttpResponseStream, HttpResponseWithStatus,
  5    RedirectPolicy, fetch, fetch_fallible, fetch_stream,
  6};
  7
  8impl HttpRequest {
  9    /// Returns a builder for an [`HttpRequest`].
 10    pub fn builder() -> HttpRequestBuilder {
 11        HttpRequestBuilder::new()
 12    }
 13
 14    /// Executes the [`HttpRequest`] with [`fetch`].
 15    pub fn fetch(&self) -> Result<HttpResponse, String> {
 16        fetch(self)
 17    }
 18
 19    /// Like [`fetch`], except it doesn't treat any status codes as errors.
 20    pub fn fetch_fallible(&self) -> Result<HttpResponseWithStatus, String> {
 21        fetch_fallible(self)
 22    }
 23
 24    /// Executes the [`HttpRequest`] with [`fetch_stream`].
 25    pub fn fetch_stream(&self) -> Result<HttpResponseStream, String> {
 26        fetch_stream(self)
 27    }
 28}
 29
 30/// A builder for an [`HttpRequest`].
 31#[derive(Clone)]
 32pub struct HttpRequestBuilder {
 33    method: Option<HttpMethod>,
 34    url: Option<String>,
 35    headers: Vec<(String, String)>,
 36    body: Option<Vec<u8>>,
 37    redirect_policy: RedirectPolicy,
 38}
 39
 40impl Default for HttpRequestBuilder {
 41    fn default() -> Self {
 42        Self::new()
 43    }
 44}
 45
 46impl HttpRequestBuilder {
 47    /// Returns a new [`HttpRequestBuilder`].
 48    pub fn new() -> Self {
 49        HttpRequestBuilder {
 50            method: None,
 51            url: None,
 52            headers: Vec::new(),
 53            body: None,
 54            redirect_policy: RedirectPolicy::NoFollow,
 55        }
 56    }
 57
 58    /// Sets the HTTP method for the request.
 59    pub fn method(mut self, method: HttpMethod) -> Self {
 60        self.method = Some(method);
 61        self
 62    }
 63
 64    /// Sets the URL for the request.
 65    pub fn url(mut self, url: impl Into<String>) -> Self {
 66        self.url = Some(url.into());
 67        self
 68    }
 69
 70    /// Adds a header to the request.
 71    pub fn header(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
 72        self.headers.push((name.into(), value.into()));
 73        self
 74    }
 75
 76    /// Adds the specified headers to the request.
 77    pub fn headers(mut self, headers: impl IntoIterator<Item = (String, String)>) -> Self {
 78        self.headers.extend(headers);
 79        self
 80    }
 81
 82    /// Sets the body of the request.
 83    pub fn body(mut self, body: impl Into<Vec<u8>>) -> Self {
 84        self.body = Some(body.into());
 85        self
 86    }
 87
 88    /// Sets the redirect policy for the request.
 89    pub fn redirect_policy(mut self, policy: RedirectPolicy) -> Self {
 90        self.redirect_policy = policy;
 91        self
 92    }
 93
 94    /// Builds the [`HttpRequest`].
 95    pub fn build(self) -> Result<HttpRequest, String> {
 96        let method = self.method.ok_or_else(|| "Method not set".to_string())?;
 97        let url = self.url.ok_or_else(|| "URL not set".to_string())?;
 98
 99        Ok(HttpRequest {
100            method,
101            url,
102            headers: self.headers,
103            body: self.body,
104            redirect_policy: self.redirect_policy,
105        })
106    }
107}