1use std::env::var_os;
5use std::ffi::OsString;
6
7use url::Url;
8
9use crate::Error;
10
11const ENV_API_URL: &str = "POLYGON_API_URL";
13const ENV_STREAM_URL: &str = "POLYGON_STREAM_URL";
15const ENV_API_KEY: &str = "POLYGON_API_KEY";
17
18const DEFAULT_API_URL: &str = "https://api.polygon.io";
20const DEFAULT_STREAM_URL: &str = "wss://socket.polygon.io";
22
23
24#[derive(Clone, Debug, PartialEq)]
27pub struct ApiInfo {
28 pub(crate) api_url: Url,
30 pub(crate) stream_url: Url,
32 pub(crate) api_key: String,
34}
35
36impl ApiInfo {
37 pub fn new<S>(api_key: S) -> Self
40 where
41 S: Into<String>,
42 {
43 Self {
44 api_url: Url::parse(DEFAULT_API_URL).unwrap(),
45 stream_url: Url::parse(DEFAULT_STREAM_URL).unwrap(),
46 api_key: api_key.into(),
47 }
48 }
49
50 pub fn from_env() -> Result<Self, Error> {
62 let api_url = var_os(ENV_API_URL)
63 .unwrap_or_else(|| OsString::from(DEFAULT_API_URL))
64 .into_string()
65 .map_err(|_| {
66 Error::Str(
67 format!(
68 "{} environment variable is not a valid string",
69 ENV_API_URL
70 )
71 .into(),
72 )
73 })?;
74 let api_url = Url::parse(&api_url)?;
75
76 let stream_url = var_os(ENV_STREAM_URL)
77 .unwrap_or_else(|| OsString::from(DEFAULT_STREAM_URL))
78 .into_string()
79 .map_err(|_| {
80 Error::Str(
81 format!(
82 "{} environment variable is not a valid string",
83 ENV_STREAM_URL
84 )
85 .into(),
86 )
87 })?;
88 let stream_url = Url::parse(&stream_url)?;
89
90 let api_key = var_os(ENV_API_KEY)
91 .ok_or_else(|| Error::Str(format!("{} environment variable not found", ENV_API_KEY).into()))?
92 .into_string()
93 .map_err(|_| {
94 Error::Str(format!("{} environment variable is not a valid string", ENV_API_KEY).into())
95 })?;
96
97 Ok(Self {
98 api_url,
99 stream_url,
100 api_key,
101 })
102 }
103}
104
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110
111 #[test]
113 fn create_api_info() {
114 let _ = ApiInfo::new("XXXXXXXXXXXXXXXXXXXX");
117 }
118}