df_hyperliquid_core/client/native/
mod.rs1pub mod socket;
13
14use crate::client::{Http, Method, Request, Response, TransportError};
15use std::time::{Duration, SystemTime, UNIX_EPOCH};
16
17pub use socket::{Event, Feed, FeedError};
18
19pub const TIMEOUT: Duration = Duration::from_secs(30);
22
23#[derive(Debug, Clone)]
25pub struct Native {
26 client: reqwest::Client,
27}
28
29impl Native {
30 #[must_use]
32 pub fn new() -> Self {
33 Native::with_timeout(TIMEOUT)
34 }
35
36 #[must_use]
40 pub fn with_timeout(timeout: Duration) -> Self {
41 let client = reqwest::Client::builder().timeout(timeout).build().unwrap_or_else(|_| reqwest::Client::new());
42 Native { client }
43 }
44}
45
46impl Default for Native {
47 fn default() -> Self {
48 Native::new()
49 }
50}
51
52impl Http for Native {
53 async fn send(&self, request: Request) -> Result<Response, TransportError> {
54 let unreachable = |error: reqwest::Error| TransportError::Unreachable(error.without_url().to_string());
55 let mut outgoing = self.client.request(method(request.method), &request.url);
56 for (name, value) in &request.headers {
57 outgoing = outgoing.header(name, value);
58 }
59 if !request.body.is_empty() {
60 outgoing = outgoing.body(request.body);
61 }
62 let answer = outgoing.send().await.map_err(unreachable)?;
63 let status = answer.status().as_u16();
64 let headers = answer
65 .headers()
66 .iter()
67 .map(|(name, value)| (name.as_str().to_owned(), String::from_utf8_lossy(value.as_bytes()).into_owned()))
68 .collect();
69 let body = answer.bytes().await.map_err(unreachable)?.to_vec();
70 Ok(Response { status, headers, body })
71 }
72}
73
74fn method(method: Method) -> reqwest::Method {
75 match method {
76 Method::Get => reqwest::Method::GET,
77 Method::Post => reqwest::Method::POST,
78 }
79}
80
81#[must_use]
84pub fn clock() -> u64 {
85 SystemTime::now().duration_since(UNIX_EPOCH).map_or(0, |since| u64::try_from(since.as_millis()).unwrap_or(u64::MAX))
86}
87
88#[cfg(test)]
89#[path = "tests/http.rs"]
90mod tests;