polyio/api/
exchanges.rs

1// Copyright (C) 2020-2022 Daniel Mueller <deso@posteo.net>
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4use serde::Deserialize;
5
6use crate::Str;
7
8
9/// An exchange as returned by the `/v1/meta/exchanges` endpoint.
10///
11/// Please note that not all fields available in a request are
12/// represented here.
13#[derive(Clone, Debug, Deserialize, PartialEq)]
14pub struct Exchange {
15  /// Exchange ID.
16  #[serde(rename = "id")]
17  pub id: usize,
18  /// The type of exchange.
19  #[serde(rename = "type")]
20  pub type_: String,
21  /// The type of market data the exchange provides.
22  #[serde(rename = "market")]
23  pub market: String,
24  /// The exchange's name.
25  #[serde(rename = "name")]
26  pub name: String,
27  /// The exchange's code.
28  ///
29  /// This field is seemingly only set for exchanges of type `Equities`.
30  pub code: Option<String>,
31}
32
33
34Endpoint! {
35  /// The representation of a GET request to the `/v1/meta/exchanges` endpoint.
36  pub Get(()),
37  Ok => Vec<Exchange>, [
38    /// The exchanges information was retrieved successfully.
39    /* 200 */ OK,
40  ],
41  Err => GetError, []
42
43  fn path(_input: &Self::Input) -> Str {
44    "/v1/meta/exchanges".into()
45  }
46}
47
48
49#[cfg(test)]
50mod tests {
51  use super::*;
52
53  use serde_json::from_str as from_json;
54
55  #[cfg(not(target_arch = "wasm32"))]
56  use test_log::test;
57
58  #[cfg(not(target_arch = "wasm32"))]
59  use crate::Client;
60
61
62  #[test]
63  fn parse_reference_exchanges() {
64    let response = r#"[
65  {
66    "id": 1,
67    "type": "exchange",
68    "market": "equities",
69    "mic": "XASE",
70    "name": "NYSE American (AMEX)",
71    "tape": "A"
72  },
73  {
74    "id": 2,
75    "type": "exchange",
76    "market": "equities",
77    "mic": "XBOS",
78    "name": "NASDAQ OMX BX",
79    "tape": "B"
80  },
81  {
82    "id": 15,
83    "type": "exchange",
84    "market": "equities",
85    "mic": "IEXG",
86    "name": "IEX",
87    "tape": "V"
88  },
89  {
90    "id": 16,
91    "type": "TRF",
92    "market": "equities",
93    "mic": "XCBO",
94    "name": "Chicago Board Options Exchange",
95    "tape": "W"
96  }
97]"#;
98
99    let exchgs = from_json::<Vec<Exchange>>(response).unwrap();
100    assert_eq!(exchgs.len(), 4);
101    assert_eq!(exchgs[0].id, 1);
102    assert_eq!(exchgs[0].type_, "exchange");
103    assert_eq!(exchgs[0].market, "equities");
104    assert_eq!(exchgs[0].name, "NYSE American (AMEX)");
105    assert_eq!(exchgs[1].id, 2);
106    assert_eq!(exchgs[2].id, 15);
107    assert_eq!(exchgs[3].id, 16);
108  }
109
110  #[cfg(not(target_arch = "wasm32"))]
111  #[test(tokio::test)]
112  async fn request_exchanges() {
113    let client = Client::from_env().unwrap();
114    let exchgs = client.issue::<Get>(()).await.unwrap();
115
116    assert!(!exchgs.is_empty());
117
118    // We are in trouble if NYE cannot be found.
119    let nye = exchgs
120      .iter()
121      .find(|exchg| exchg.code.as_deref() == Some("NYE"))
122      .unwrap();
123    assert_eq!(nye.type_, "exchange");
124    assert_eq!(nye.market, "equities");
125  }
126}