Files
oak-gpui/crates/gpui/src/http_client.rs
T
Mike-Solar af5482d774 style: cargo fmt with the workspace tab policy (hard_tabs)
Whitespace only; the fork has no own rustfmt.toml so the Oak root
policy applies.
2026-08-11 23:06:13 +08:00

106 lines
2.2 KiB
Rust

use futures::future::BoxFuture;
use http::StatusCode;
/// A simple HTTP response.
pub struct HttpResponse {
/// The HTTP status code.
pub status: StatusCode,
/// The response body bytes.
pub body: Vec<u8>,
}
/// A trait for making HTTP requests.
pub trait HttpClient: 'static + Send + Sync {
/// Perform a GET request and return the full response.
fn get(
&self,
url: &str,
follow_redirects: bool,
) -> BoxFuture<'static, anyhow::Result<HttpResponse>>;
}
/// An HTTP client that always returns an error.
pub struct NullHttpClient;
impl HttpClient for NullHttpClient {
fn get(
&self,
_url: &str,
_follow_redirects: bool,
) -> BoxFuture<'static, anyhow::Result<HttpResponse>> {
Box::pin(async { anyhow::bail!("No HttpClient available") })
}
}
/// An HTTP client that blocks all requests.
pub struct BlockedHttpClient;
impl BlockedHttpClient {
/// Create a new `BlockedHttpClient`.
pub fn new() -> Self {
Self
}
}
impl Default for BlockedHttpClient {
fn default() -> Self {
Self
}
}
impl HttpClient for BlockedHttpClient {
fn get(
&self,
_url: &str,
_follow_redirects: bool,
) -> BoxFuture<'static, anyhow::Result<HttpResponse>> {
Box::pin(async {
Err(std::io::Error::new(
std::io::ErrorKind::PermissionDenied,
"BlockedHttpClient disallowed request",
)
.into())
})
}
}
/// A fake HTTP client for testing.
#[cfg(any(test, feature = "test-support"))]
pub struct FakeHttpClient {
status: StatusCode,
}
#[cfg(any(test, feature = "test-support"))]
impl FakeHttpClient {
/// Create a fake client that returns 404 responses.
pub fn with_404_response() -> std::sync::Arc<dyn HttpClient> {
std::sync::Arc::new(Self {
status: StatusCode::NOT_FOUND,
})
}
/// Create a fake client that returns 200 responses.
pub fn with_200_response() -> std::sync::Arc<dyn HttpClient> {
std::sync::Arc::new(Self {
status: StatusCode::OK,
})
}
}
#[cfg(any(test, feature = "test-support"))]
impl HttpClient for FakeHttpClient {
fn get(
&self,
_url: &str,
_follow_redirects: bool,
) -> BoxFuture<'static, anyhow::Result<HttpResponse>> {
let status = self.status;
Box::pin(async move {
Ok(HttpResponse {
status,
body: Vec::new(),
})
})
}
}