financeapi/
autocomplete.rs1use crate::FinanceapiError;
2use serde::Deserialize;
3
4#[derive(Deserialize, Debug, Default)]
5#[serde(rename_all = "camelCase")]
6pub struct FinanceapiAutocomplete {
7 pub symbol: String,
8 pub name: String,
9 pub exch: String,
10 #[serde(rename(deserialize = "type"))]
11 pub exch_type: String,
12 pub exch_disp: String,
13 pub type_disp: String,
14}
15
16#[derive(Deserialize, Debug)]
17#[serde(rename_all = "PascalCase")]
18struct ResultSet {
19 _query: Option<String>,
20 result: Vec<FinanceapiAutocomplete>,
21}
22
23impl FinanceapiAutocomplete {
24 pub fn from_json(
26 json: serde_json::Value,
27 ) -> Result<Vec<FinanceapiAutocomplete>, FinanceapiError> {
28 let rs: ResultSet = serde_json::from_value(
29 json.get("ResultSet")
30 .ok_or(FinanceapiError::JsonParseError)?
31 .to_owned(),
32 )?;
33
34 if rs.result.is_empty() {
35 return Err(FinanceapiError::SymbolNotFoundError);
36 }
37
38 Ok(rs.result)
39 }
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use serde_json::json;
46
47 #[test]
48 #[should_panic(expected = "JsonParseError")]
49 fn wrong_json() {
50 let j = json!({ "var": 200 });
51 FinanceapiAutocomplete::from_json(j).unwrap();
52 }
53
54 #[test]
55 #[should_panic(expected = "SymbolNotFoundError")]
56 fn wrong_symbol() {
57 let j = json!({
58 "ResultSet": {
59 "Query": "unknown",
60 "Result": []
61 }
62 });
63 FinanceapiAutocomplete::from_json(j).unwrap();
64 }
65
66 #[test]
67 #[should_panic(expected = "JsonSerdeError")]
68 fn wrong_json_serde() {
69 let j = json!({
70 "ResultSet": {
71 "Query": "VWCE.MI",
72 "Result": [
73 {
74 "symbol": "VWCE.MI",
75 }
76 ]
77 }
78 });
79 FinanceapiAutocomplete::from_json(j).unwrap();
80 }
81
82 #[test]
83 fn check_parsing() {
84 let j = json!({
85 "ResultSet": {
86 "Query": "VWCE.MI",
87 "Result": [
88 {
89 "symbol": "VWCE.MI",
90 "name": "Vanguard FTSE All-World UCITS ETF USD Accumulation",
91 "exch": "MIL",
92 "type": "E",
93 "exchDisp": "Milan",
94 "typeDisp": "ETF"
95 }
96 ]
97 }
98 });
99
100 let vq = FinanceapiAutocomplete::from_json(j).unwrap();
101 assert_eq!(vq.len(), 1);
102
103 let query = &vq[0];
104 assert_eq!(query.symbol, "VWCE.MI");
105 assert_eq!(query.exch, "MIL");
106 }
107}