longbridge_httpcli/
client.rs1use std::sync::Arc;
2
3use reqwest::{
4 Client, Method,
5 header::{HeaderMap, HeaderName, HeaderValue},
6};
7use serde::Deserialize;
8
9use crate::{HttpClientConfig, HttpClientError, HttpClientResult, Json, RequestBuilder};
10
11#[derive(Clone)]
13pub struct HttpClient {
14 pub(crate) http_cli: Client,
15 pub(crate) config: Arc<HttpClientConfig>,
16 pub(crate) default_headers: HeaderMap,
17}
18
19impl HttpClient {
20 pub fn new(config: HttpClientConfig) -> Self {
22 Self {
23 http_cli: Client::new(),
24 config: Arc::new(config),
25 default_headers: HeaderMap::new(),
26 }
27 }
28
29 pub fn header<K, V>(mut self, key: K, value: V) -> Self
31 where
32 K: TryInto<HeaderName>,
33 V: TryInto<HeaderValue>,
34 {
35 let key = key.try_into();
36 let value = value.try_into();
37 if let (Ok(key), Ok(value)) = (key, value) {
38 self.default_headers.insert(key, value);
39 }
40 self
41 }
42
43 #[inline]
45 pub fn request(
46 &self,
47 method: Method,
48 path: impl Into<String>,
49 ) -> RequestBuilder<'_, (), (), ()> {
50 RequestBuilder::new(self, method, path)
51 }
52
53 pub async fn get_otp(&self) -> HttpClientResult<String> {
57 #[derive(Debug, Deserialize)]
58 struct Response {
59 otp: String,
60 limit: i32,
61 online: i32,
62 }
63
64 let resp = self
65 .request(Method::GET, "/v1/socket/token")
66 .response::<Json<Response>>()
67 .send()
68 .await?
69 .0;
70 tracing::info!(limit = resp.limit, online = resp.online, "create otp");
71
72 if resp.online >= resp.limit {
73 return Err(HttpClientError::ConnectionLimitExceeded {
74 limit: resp.limit,
75 online: resp.online,
76 });
77 }
78
79 Ok(resp.otp)
80 }
81}