finance_query/models/fundamentals/
summary_detail.rs1use crate::models::format::{Both, Format};
2use finance_query_derive::FormatConvert;
3use serde::{Deserialize, Serialize};
7use serde_json::Value;
8
9#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, FormatConvert)]
21#[serde(rename_all = "camelCase", bound = "")]
22#[non_exhaustive]
23pub struct SummaryDetail<F: Format = Both> {
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub algorithm: Option<Value>,
27
28 #[serde(skip_serializing_if = "Option::is_none")]
30 pub all_time_high: Option<F::Value<f64>>,
31
32 #[serde(skip_serializing_if = "Option::is_none")]
34 pub all_time_low: Option<F::Value<f64>>,
35
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub ask: Option<F::Value<f64>>,
39
40 #[serde(skip_serializing_if = "Option::is_none")]
42 pub ask_size: Option<F::Value<i64>>,
43
44 #[serde(skip_serializing_if = "Option::is_none")]
46 pub average_daily_volume10_day: Option<F::Value<i64>>,
47
48 #[serde(skip_serializing_if = "Option::is_none")]
50 pub average_volume: Option<F::Value<i64>>,
51
52 #[serde(skip_serializing_if = "Option::is_none")]
54 pub average_volume10days: Option<F::Value<i64>>,
55
56 #[serde(skip_serializing_if = "Option::is_none")]
58 pub beta: Option<F::Value<f64>>,
59
60 #[serde(skip_serializing_if = "Option::is_none")]
62 pub bid: Option<F::Value<f64>>,
63
64 #[serde(skip_serializing_if = "Option::is_none")]
66 pub bid_size: Option<F::Value<i64>>,
67
68 #[serde(skip_serializing_if = "Option::is_none")]
70 pub circulating_supply: Option<Value>,
71
72 #[serde(skip_serializing_if = "Option::is_none")]
74 pub coin_market_cap_link: Option<Value>,
75
76 #[serde(skip_serializing_if = "Option::is_none")]
78 pub currency: Option<String>,
79
80 #[serde(skip_serializing_if = "Option::is_none")]
82 pub day_high: Option<F::Value<f64>>,
83
84 #[serde(skip_serializing_if = "Option::is_none")]
86 pub day_low: Option<F::Value<f64>>,
87
88 #[serde(skip_serializing_if = "Option::is_none")]
90 pub dividend_rate: Option<F::Value<f64>>,
91
92 #[serde(skip_serializing_if = "Option::is_none")]
94 pub dividend_yield: Option<F::Value<f64>>,
95
96 #[serde(skip_serializing_if = "Option::is_none")]
98 pub ex_dividend_date: Option<F::Value<i64>>,
99
100 #[serde(skip_serializing_if = "Option::is_none")]
102 pub expire_date: Option<Value>,
103
104 #[serde(skip_serializing_if = "Option::is_none")]
106 pub fifty_day_average: Option<F::Value<f64>>,
107
108 #[serde(skip_serializing_if = "Option::is_none")]
110 pub fifty_two_week_high: Option<F::Value<f64>>,
111
112 #[serde(skip_serializing_if = "Option::is_none")]
114 pub fifty_two_week_low: Option<F::Value<f64>>,
115
116 #[serde(skip_serializing_if = "Option::is_none")]
118 pub five_year_avg_dividend_yield: Option<F::Value<f64>>,
119
120 #[serde(rename = "forwardPE", skip_serializing_if = "Option::is_none")]
122 pub forward_pe: Option<F::Value<f64>>,
123
124 #[serde(skip_serializing_if = "Option::is_none")]
126 pub from_currency: Option<String>,
127
128 #[serde(skip_serializing_if = "Option::is_none")]
130 pub last_market: Option<String>,
131
132 #[serde(skip_serializing_if = "Option::is_none")]
134 pub market_cap: Option<F::Value<i64>>,
135
136 #[serde(skip_serializing_if = "Option::is_none")]
138 pub max_age: Option<i64>,
139
140 #[serde(skip_serializing_if = "Option::is_none")]
142 pub max_supply: Option<Value>,
143
144 #[serde(skip_serializing_if = "Option::is_none")]
146 pub nav_price: Option<F::Value<f64>>,
147
148 #[serde(skip_serializing_if = "Option::is_none")]
150 pub open: Option<F::Value<f64>>,
151
152 #[serde(skip_serializing_if = "Option::is_none")]
154 pub open_interest: Option<Value>,
155
156 #[serde(skip_serializing_if = "Option::is_none")]
158 pub payout_ratio: Option<F::Value<f64>>,
159
160 #[serde(skip_serializing_if = "Option::is_none")]
162 pub previous_close: Option<F::Value<f64>>,
163
164 #[serde(skip_serializing_if = "Option::is_none")]
166 pub price_hint: Option<F::Value<i64>>,
167
168 #[serde(skip_serializing_if = "Option::is_none")]
170 pub price_to_sales_trailing12_months: Option<F::Value<f64>>,
171
172 #[serde(skip_serializing_if = "Option::is_none")]
174 pub qtd_return: Option<Value>,
175
176 #[serde(skip_serializing_if = "Option::is_none")]
178 pub regular_market_day_high: Option<F::Value<f64>>,
179
180 #[serde(skip_serializing_if = "Option::is_none")]
182 pub regular_market_day_low: Option<F::Value<f64>>,
183
184 #[serde(skip_serializing_if = "Option::is_none")]
186 pub regular_market_open: Option<F::Value<f64>>,
187
188 #[serde(skip_serializing_if = "Option::is_none")]
190 pub regular_market_previous_close: Option<F::Value<f64>>,
191
192 #[serde(skip_serializing_if = "Option::is_none")]
194 pub regular_market_volume: Option<F::Value<i64>>,
195
196 #[serde(skip_serializing_if = "Option::is_none")]
198 pub start_date: Option<Value>,
199
200 #[serde(skip_serializing_if = "Option::is_none")]
202 pub strike_price: Option<Value>,
203
204 #[serde(skip_serializing_if = "Option::is_none")]
206 pub to_currency: Option<String>,
207
208 #[serde(skip_serializing_if = "Option::is_none")]
210 pub total_assets: Option<F::Value<i64>>,
211
212 #[serde(skip_serializing_if = "Option::is_none")]
214 pub tradeable: Option<bool>,
215
216 #[serde(skip_serializing_if = "Option::is_none")]
218 pub trailing_annual_dividend_rate: Option<F::Value<f64>>,
219
220 #[serde(skip_serializing_if = "Option::is_none")]
222 pub trailing_annual_dividend_yield: Option<F::Value<f64>>,
223
224 #[serde(rename = "trailingPE", skip_serializing_if = "Option::is_none")]
226 pub trailing_pe: Option<F::Value<f64>>,
227
228 #[serde(skip_serializing_if = "Option::is_none")]
230 pub two_hundred_day_average: Option<F::Value<f64>>,
231
232 #[serde(skip_serializing_if = "Option::is_none")]
234 pub volume: Option<F::Value<i64>>,
235
236 #[serde(skip_serializing_if = "Option::is_none")]
238 pub volume24_hr: Option<Value>,
239
240 #[serde(skip_serializing_if = "Option::is_none")]
242 pub volume_all_currencies: Option<Value>,
243
244 #[serde(rename = "yield", skip_serializing_if = "Option::is_none")]
246 pub yield_value: Option<F::Value<f64>>,
247
248 #[serde(skip_serializing_if = "Option::is_none")]
250 pub ytd_return: Option<Value>,
251}
252
253#[cfg(test)]
254mod tests {
255 use super::*;
256
257 #[test]
258 fn test_deserialize_summary_detail() {
259 let json = r#"{
260 "currency": "USD",
261 "previousClose": {"fmt": "275.00", "raw": 275.0},
262 "marketCap": {"fmt": "4.09T", "longFmt": "4,090,000,000,000", "raw": 4090000000000},
263 "beta": {"fmt": "1.11", "raw": 1.109},
264 "tradeable": true
265 }"#;
266
267 let detail: SummaryDetail = serde_json::from_str(json).unwrap();
268 assert_eq!(detail.currency.as_deref(), Some("USD"));
269 assert_eq!(
270 detail.previous_close.as_ref().map(|v| v.raw),
271 Some(Some(275.0))
272 );
273 assert_eq!(
274 detail.market_cap.as_ref().map(|v| v.raw),
275 Some(Some(4090000000000))
276 );
277 assert_eq!(detail.tradeable, Some(true));
278 }
279
280 #[test]
281 fn test_into_raw() {
282 let json = r#"{
283 "currency": "USD",
284 "previousClose": {"fmt": "275.00", "raw": 275.0},
285 "beta": {"fmt": "1.11", "raw": 1.109}
286 }"#;
287
288 let detail: SummaryDetail = serde_json::from_str(json).unwrap();
289 let raw = detail.into_raw();
290 assert_eq!(raw.currency.as_deref(), Some("USD"));
291 assert_eq!(raw.previous_close, Some(275.0));
292 assert_eq!(raw.beta, Some(1.109));
293 }
294
295 #[test]
296 fn test_into_pretty() {
297 let json = r#"{
298 "previousClose": {"fmt": "275.00", "raw": 275.0},
299 "marketCap": {"fmt": "4.09T", "longFmt": "4,090,000,000,000", "raw": 4090000000000}
300 }"#;
301
302 let detail: SummaryDetail = serde_json::from_str(json).unwrap();
303 let pretty = detail.into_pretty();
304 assert_eq!(pretty.previous_close.as_deref(), Some("275.00"));
305 assert_eq!(pretty.market_cap.as_deref(), Some("4.09T"));
306 }
307}