finance_query/models/market/
index_trend.rs1use crate::models::quote::FormattedValue;
2use serde::{Deserialize, Serialize};
3
4#[derive(Default, Debug, Clone, Serialize, Deserialize)]
6#[serde(rename_all = "camelCase")]
7#[non_exhaustive]
8pub struct IndexTrend {
9 #[serde(default)]
11 pub max_age: Option<i64>,
12
13 #[serde(default)]
15 pub symbol: Option<String>,
16
17 #[serde(default)]
19 pub estimates: Option<Vec<TrendEstimate>>,
20
21 #[serde(default)]
23 pub pe_ratio: Option<FormattedValue<f64>>,
24
25 #[serde(default)]
27 pub peg_ratio: Option<FormattedValue<f64>>,
28}
29
30#[derive(Default, Debug, Clone, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase")]
33#[non_exhaustive]
34pub struct IndustryTrend {
35 #[serde(default)]
37 pub max_age: Option<i64>,
38
39 #[serde(default)]
41 pub symbol: Option<String>,
42
43 #[serde(default)]
45 pub estimates: Option<Vec<TrendEstimate>>,
46
47 #[serde(default)]
49 pub pe_ratio: Option<FormattedValue<f64>>,
50
51 #[serde(default)]
53 pub peg_ratio: Option<FormattedValue<f64>>,
54}
55
56#[derive(Default, Debug, Clone, Serialize, Deserialize)]
58#[serde(rename_all = "camelCase")]
59#[non_exhaustive]
60pub struct SectorTrend {
61 #[serde(default)]
63 pub max_age: Option<i64>,
64
65 #[serde(default)]
67 pub symbol: Option<String>,
68
69 #[serde(default)]
71 pub estimates: Option<Vec<TrendEstimate>>,
72
73 #[serde(default)]
75 pub pe_ratio: Option<FormattedValue<f64>>,
76
77 #[serde(default)]
79 pub peg_ratio: Option<FormattedValue<f64>>,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
84#[serde(rename_all = "camelCase")]
85pub struct TrendEstimate {
86 #[serde(default)]
88 pub period: Option<String>,
89
90 #[serde(default)]
92 pub growth: Option<FormattedValue<f64>>,
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98 use serde_json;
99
100 #[test]
101 fn test_index_trend_deserialize() {
102 let json = r#"{
103 "maxAge": 1,
104 "symbol": "SP5",
105 "estimates": [
106 {
107 "period": "0q",
108 "growth": {"raw": 0.1516, "fmt": "0.15"}
109 },
110 {
111 "period": "+1q",
112 "growth": {"raw": 0.067600004, "fmt": "0.07"}
113 }
114 ],
115 "peRatio": {},
116 "pegRatio": {}
117 }"#;
118
119 let result: Result<IndexTrend, _> = serde_json::from_str(json);
120 assert!(
121 result.is_ok(),
122 "IndexTrend should deserialize successfully: {:?}",
123 result.err()
124 );
125
126 let trend = result.unwrap();
127 assert_eq!(trend.max_age, Some(1));
128 assert_eq!(trend.symbol, Some("SP5".to_string()));
129 assert!(trend.estimates.is_some());
130 assert_eq!(trend.estimates.as_ref().unwrap().len(), 2);
131
132 assert_eq!(
134 trend.pe_ratio,
135 Some(FormattedValue {
136 fmt: None,
137 long_fmt: None,
138 raw: None
139 })
140 );
141 assert_eq!(
142 trend.peg_ratio,
143 Some(FormattedValue {
144 fmt: None,
145 long_fmt: None,
146 raw: None
147 })
148 );
149 }
150
151 #[test]
152 fn test_index_trend_empty() {
153 let json = r#"{"maxAge": 1, "symbol": null, "estimates": []}"#;
154 let result: Result<IndexTrend, _> = serde_json::from_str(json);
155 assert!(result.is_ok());
156 }
157}