alpaca_data/crypto/
client.rs1use std::fmt;
2use std::sync::Arc;
3
4use alpaca_http::RequestParts;
5use reqwest::Method;
6use serde::de::DeserializeOwned;
7
8use crate::{Error, client::ClientInner, pagination};
9
10use super::{
11 BarsRequest, BarsResponse, LatestBarsRequest, LatestBarsResponse, LatestOrderbooksRequest,
12 LatestOrderbooksResponse, LatestQuotesRequest, LatestQuotesResponse, LatestTradesRequest,
13 LatestTradesResponse, QuotesRequest, QuotesResponse, SnapshotsRequest, SnapshotsResponse,
14 TradesRequest, TradesResponse,
15};
16
17#[derive(Clone)]
18pub struct CryptoClient {
19 inner: Arc<ClientInner>,
20}
21
22impl CryptoClient {
23 pub(crate) fn new(inner: Arc<ClientInner>) -> Self {
24 Self { inner }
25 }
26
27 pub async fn bars(&self, request: BarsRequest) -> Result<BarsResponse, Error> {
28 request.validate()?;
29 let path = format!("/v1beta3/crypto/{}/bars", request.location);
30 self.get_json("crypto.bars", path, request.into_query())
31 .await
32 }
33
34 pub async fn bars_all(&self, request: BarsRequest) -> Result<BarsResponse, Error> {
35 let client = self.clone();
36 pagination::collect_all(request, move |request| {
37 let client = client.clone();
38 async move { client.bars(request).await }
39 })
40 .await
41 }
42
43 pub async fn quotes(&self, request: QuotesRequest) -> Result<QuotesResponse, Error> {
44 request.validate()?;
45 let path = format!("/v1beta3/crypto/{}/quotes", request.location);
46 self.get_json("crypto.quotes", path, request.into_query())
47 .await
48 }
49
50 pub async fn quotes_all(&self, request: QuotesRequest) -> Result<QuotesResponse, Error> {
51 let client = self.clone();
52 pagination::collect_all(request, move |request| {
53 let client = client.clone();
54 async move { client.quotes(request).await }
55 })
56 .await
57 }
58
59 pub async fn trades(&self, request: TradesRequest) -> Result<TradesResponse, Error> {
60 request.validate()?;
61 let path = format!("/v1beta3/crypto/{}/trades", request.location);
62 self.get_json("crypto.trades", path, request.into_query())
63 .await
64 }
65
66 pub async fn trades_all(&self, request: TradesRequest) -> Result<TradesResponse, Error> {
67 let client = self.clone();
68 pagination::collect_all(request, move |request| {
69 let client = client.clone();
70 async move { client.trades(request).await }
71 })
72 .await
73 }
74
75 pub async fn latest_bars(
76 &self,
77 request: LatestBarsRequest,
78 ) -> Result<LatestBarsResponse, Error> {
79 request.validate()?;
80 let path = format!("/v1beta3/crypto/{}/latest/bars", request.location);
81 self.get_json("crypto.latest_bars", path, request.into_query())
82 .await
83 }
84
85 pub async fn latest_quotes(
86 &self,
87 request: LatestQuotesRequest,
88 ) -> Result<LatestQuotesResponse, Error> {
89 request.validate()?;
90 let path = format!("/v1beta3/crypto/{}/latest/quotes", request.location);
91 self.get_json("crypto.latest_quotes", path, request.into_query())
92 .await
93 }
94
95 pub async fn latest_trades(
96 &self,
97 request: LatestTradesRequest,
98 ) -> Result<LatestTradesResponse, Error> {
99 request.validate()?;
100 let path = format!("/v1beta3/crypto/{}/latest/trades", request.location);
101 self.get_json("crypto.latest_trades", path, request.into_query())
102 .await
103 }
104
105 pub async fn latest_orderbooks(
106 &self,
107 request: LatestOrderbooksRequest,
108 ) -> Result<LatestOrderbooksResponse, Error> {
109 request.validate()?;
110 let path = format!("/v1beta3/crypto/{}/latest/orderbooks", request.location);
111 self.get_json("crypto.latest_orderbooks", path, request.into_query())
112 .await
113 }
114
115 pub async fn snapshots(&self, request: SnapshotsRequest) -> Result<SnapshotsResponse, Error> {
116 request.validate()?;
117 let path = format!("/v1beta3/crypto/{}/snapshots", request.location);
118 self.get_json("crypto.snapshots", path, request.into_query())
119 .await
120 }
121
122 #[allow(dead_code)]
123 #[must_use]
124 pub(crate) fn inner(&self) -> &Arc<ClientInner> {
125 &self.inner
126 }
127
128 async fn get_json<Response>(
129 &self,
130 operation: &'static str,
131 path: impl Into<String>,
132 query: Vec<(String, String)>,
133 ) -> Result<Response, Error>
134 where
135 Response: DeserializeOwned,
136 {
137 let request = RequestParts::new(Method::GET, path.into())
138 .with_operation(operation)
139 .with_query(query);
140
141 self.inner
142 .send_json::<Response>(request)
143 .await
144 .map(|response| response.into_body())
145 }
146}
147
148impl fmt::Debug for CryptoClient {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 f.debug_struct("CryptoClient").finish()
151 }
152}