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