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