1use crate::config::{DEFAULT_BASE_URL, DEFAULT_WS_URL, RadionConfig};
4use crate::error::{RadionError, Result};
5
6#[derive(Debug)]
14#[non_exhaustive]
15pub struct Radion {
16 pub config: RadionConfig,
18
19 #[cfg(feature = "realtime")]
21 #[cfg_attr(docsrs, doc(cfg(feature = "realtime")))]
22 pub realtime: crate::realtime::RealtimeClient,
23}
24
25impl Radion {
26 pub fn builder() -> RadionBuilder {
28 RadionBuilder::default()
29 }
30}
31
32#[derive(Debug, Default)]
43pub struct RadionBuilder {
44 api_key: Option<String>,
45 base_url: Option<String>,
46 ws_url: Option<String>,
47 #[cfg(feature = "realtime")]
48 token_provider: Option<crate::realtime::TokenProvider>,
49 #[cfg(feature = "realtime")]
50 auth_in_query: bool,
51 #[cfg(feature = "compression")]
52 compression: bool,
53}
54
55impl RadionBuilder {
56 #[must_use]
58 pub fn api_key(mut self, api_key: impl Into<String>) -> Self {
59 self.api_key = Some(api_key.into());
60 self
61 }
62
63 #[must_use]
65 pub fn base_url(mut self, base_url: impl Into<String>) -> Self {
66 self.base_url = Some(base_url.into());
67 self
68 }
69
70 #[must_use]
72 pub fn ws_url(mut self, ws_url: impl Into<String>) -> Self {
73 self.ws_url = Some(ws_url.into());
74 self
75 }
76
77 #[cfg(feature = "realtime")]
79 #[cfg_attr(docsrs, doc(cfg(feature = "realtime")))]
80 #[must_use]
81 pub fn token(mut self, token: impl Into<String>) -> Self {
82 self.token_provider = Some(crate::realtime::TokenProvider::from_static(token));
83 self
84 }
85
86 #[cfg(feature = "realtime")]
88 #[cfg_attr(docsrs, doc(cfg(feature = "realtime")))]
89 #[must_use]
90 pub fn token_provider(mut self, provider: crate::realtime::TokenProvider) -> Self {
91 self.token_provider = Some(provider);
92 self
93 }
94
95 #[cfg(feature = "realtime")]
97 #[cfg_attr(docsrs, doc(cfg(feature = "realtime")))]
98 #[must_use]
99 pub fn auth_in_query(mut self, enabled: bool) -> Self {
100 self.auth_in_query = enabled;
101 self
102 }
103
104 #[cfg(feature = "compression")]
106 #[cfg_attr(docsrs, doc(cfg(feature = "compression")))]
107 #[must_use]
108 pub fn compression(mut self, enabled: bool) -> Self {
109 self.compression = enabled;
110 self
111 }
112
113 pub fn build(self) -> Result<Radion> {
119 let api_key = self.api_key.unwrap_or_default();
120 if api_key.is_empty() {
121 return Err(RadionError::connection("api_key is required"));
122 }
123 let config = RadionConfig {
124 api_key: api_key.clone(),
125 base_url: self
126 .base_url
127 .unwrap_or_else(|| DEFAULT_BASE_URL.to_string()),
128 ws_url: self.ws_url.unwrap_or_else(|| DEFAULT_WS_URL.to_string()),
129 };
130
131 #[cfg(feature = "realtime")]
132 let realtime = {
133 let mut options = crate::realtime::RealtimeOptions::new(api_key)
134 .url(config.ws_url.clone())
135 .auth_in_query(self.auth_in_query);
136 #[cfg(feature = "compression")]
137 {
138 options = options.compression(self.compression);
139 }
140 if let Some(provider) = self.token_provider {
141 options = options.token_provider(provider);
142 }
143 crate::realtime::RealtimeClient::new(options)
144 };
145
146 Ok(Radion {
147 config,
148 #[cfg(feature = "realtime")]
149 realtime,
150 })
151 }
152}
153
154#[cfg(all(test, feature = "realtime"))]
155mod builder_tests {
156 use super::*;
157
158 #[test]
159 fn builder_accepts_token_and_query_flag() {
160 let radion = Radion::builder()
161 .api_key("pk_jwt_x")
162 .token("jwt")
163 .auth_in_query(true)
164 .build()
165 .expect("builds");
166 let _ = radion;
167 }
168
169 #[cfg(feature = "compression")]
170 #[test]
171 fn builder_forwards_compression_to_the_realtime_options() {
172 let radion = Radion::builder()
173 .api_key("sk_x")
174 .compression(true)
175 .build()
176 .expect("builds");
177 let _ = radion;
178 }
179}