Skip to main content

alpaca_data/crypto/
response.rs

1use std::collections::HashMap;
2
3use alpaca_core::pagination::PaginatedResponse;
4use serde::{Deserialize, Serialize};
5
6use super::{Bar, Orderbook, Quote, Snapshot, Trade};
7
8#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
9pub struct BarsResponse {
10    #[serde(default)]
11    pub bars: HashMap<String, Vec<Bar>>,
12    pub next_page_token: Option<String>,
13}
14
15#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
16pub struct QuotesResponse {
17    #[serde(default)]
18    pub quotes: HashMap<String, Vec<Quote>>,
19    pub next_page_token: Option<String>,
20}
21
22#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
23pub struct TradesResponse {
24    #[serde(default)]
25    pub trades: HashMap<String, Vec<Trade>>,
26    pub next_page_token: Option<String>,
27}
28
29#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
30pub struct LatestBarsResponse {
31    #[serde(default)]
32    pub bars: HashMap<String, Bar>,
33}
34
35#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
36pub struct LatestQuotesResponse {
37    #[serde(default)]
38    pub quotes: HashMap<String, Quote>,
39}
40
41#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
42pub struct LatestTradesResponse {
43    #[serde(default)]
44    pub trades: HashMap<String, Trade>,
45}
46
47#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
48pub struct LatestOrderbooksResponse {
49    #[serde(default)]
50    pub orderbooks: HashMap<String, Orderbook>,
51}
52
53#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
54pub struct SnapshotsResponse {
55    #[serde(default)]
56    pub snapshots: HashMap<String, Snapshot>,
57}
58
59impl PaginatedResponse for BarsResponse {
60    fn next_page_token(&self) -> Option<&str> {
61        self.next_page_token.as_deref()
62    }
63
64    fn merge_page(&mut self, next: Self) -> Result<(), alpaca_core::Error> {
65        merge_batch_page(&mut self.bars, next.bars);
66        self.next_page_token = next.next_page_token;
67        Ok(())
68    }
69
70    fn clear_next_page_token(&mut self) {
71        self.next_page_token = None;
72    }
73}
74
75impl PaginatedResponse for QuotesResponse {
76    fn next_page_token(&self) -> Option<&str> {
77        self.next_page_token.as_deref()
78    }
79
80    fn merge_page(&mut self, next: Self) -> Result<(), alpaca_core::Error> {
81        merge_batch_page(&mut self.quotes, next.quotes);
82        self.next_page_token = next.next_page_token;
83        Ok(())
84    }
85
86    fn clear_next_page_token(&mut self) {
87        self.next_page_token = None;
88    }
89}
90
91impl PaginatedResponse for TradesResponse {
92    fn next_page_token(&self) -> Option<&str> {
93        self.next_page_token.as_deref()
94    }
95
96    fn merge_page(&mut self, next: Self) -> Result<(), alpaca_core::Error> {
97        merge_batch_page(&mut self.trades, next.trades);
98        self.next_page_token = next.next_page_token;
99        Ok(())
100    }
101
102    fn clear_next_page_token(&mut self) {
103        self.next_page_token = None;
104    }
105}
106
107fn merge_batch_page<Item>(
108    current: &mut HashMap<String, Vec<Item>>,
109    next: HashMap<String, Vec<Item>>,
110) {
111    for (symbol, mut items) in next {
112        current.entry(symbol).or_default().append(&mut items);
113    }
114}