1use once_cell::sync::Lazy;
6use reqwest::{header::USER_AGENT, Client, Response, StatusCode};
7
8use crate::{
9 errors::{ConnpassCliError, ConnpassResult, HttpResponseError},
10 query::Query,
11 response::ConnpassResponse,
12};
13
14const BASE_URL: &str = "https://connpass.com/api/v1/event/";
15static CRATE_USER_AGENT: Lazy<String> = Lazy::new(|| {
16 format!(
17 "connpass-rs/{} (+https://github.com/yuk1ty/connpass-rs)",
18 env!("CARGO_PKG_VERSION")
19 )
20});
21
22#[derive(Clone)]
24pub struct ConnpassClient {
25 client: Client,
26}
27
28impl Default for ConnpassClient {
29 fn default() -> Self {
30 ConnpassClient {
31 client: Client::new(),
32 }
33 }
34}
35
36impl ConnpassClient {
37 pub fn new() -> Self {
38 ConnpassClient::default()
39 }
40
41 pub fn with_client(client: Client) -> Self {
43 ConnpassClient { client }
44 }
45
46 pub async fn send_request(self, query: Query) -> ConnpassResult<ConnpassResponse> {
72 let response = self
73 .client
74 .get(BASE_URL)
75 .header(USER_AGENT, CRATE_USER_AGENT.as_str())
76 .query(&query.make_reqwest_query())
77 .send()
78 .await
79 .map_err(|err| ConnpassCliError::HttpResponse(HttpResponseError::ReqwestError(err)))?;
80 self.handler(response).await
81 }
82
83 async fn handler(&self, res: Response) -> ConnpassResult<ConnpassResponse> {
84 dbg!("response = {}", &res);
85 match res.status() {
86 StatusCode::OK => res.json::<ConnpassResponse>().await.map_err(|err| {
87 ConnpassCliError::HttpResponse(HttpResponseError::JsonDecode(format!("{}", err)))
88 }),
89 StatusCode::FORBIDDEN => {
90 Err(ConnpassCliError::HttpResponse(HttpResponseError::Forbidden))
91 }
92 StatusCode::INTERNAL_SERVER_ERROR => Err(ConnpassCliError::HttpResponse(
93 HttpResponseError::InternalServerError,
94 )),
95 StatusCode::SERVICE_UNAVAILABLE => Err(ConnpassCliError::HttpResponse(
96 HttpResponseError::ServiceUnavailable,
97 )),
98 s => Err(ConnpassCliError::HttpResponse(HttpResponseError::Various(
99 format!("Unexpected response received: {:?} (status code)", s),
100 ))),
101 }
102 }
103}
104
105#[cfg(feature = "blocking")]
107pub mod blocking {
108 use reqwest::{
109 blocking::{Client, Response},
110 header::USER_AGENT,
111 StatusCode,
112 };
113
114 use crate::{
115 errors::{ConnpassCliError, ConnpassResult, HttpResponseError},
116 query::Query,
117 response::ConnpassResponse,
118 };
119
120 use super::{BASE_URL, CRATE_USER_AGENT};
121
122 pub struct ConnpassClient {
124 client: Client,
125 }
126
127 impl Default for ConnpassClient {
128 fn default() -> Self {
129 ConnpassClient {
130 client: Client::new(),
131 }
132 }
133 }
134
135 impl ConnpassClient {
136 pub fn new() -> Self {
137 ConnpassClient::default()
138 }
139
140 pub fn with_client(client: Client) -> Self {
142 ConnpassClient { client }
143 }
144
145 #[allow(clippy::needless_doctest_main)]
170 pub fn send_request(self, query: Query) -> ConnpassResult<ConnpassResponse> {
171 let response = self
172 .client
173 .get(BASE_URL)
174 .header(USER_AGENT, CRATE_USER_AGENT.as_str())
175 .query(&query.make_reqwest_query())
176 .send()
177 .map_err(|err| {
178 ConnpassCliError::HttpResponse(HttpResponseError::ReqwestError(err))
179 })?;
180
181 self.handler(response)
182 }
183
184 fn handler(&self, res: Response) -> ConnpassResult<ConnpassResponse> {
185 dbg!("response = {}", &res);
186 match res.status() {
187 StatusCode::OK => res.json::<ConnpassResponse>().map_err(|err| {
188 ConnpassCliError::HttpResponse(HttpResponseError::JsonDecode(format!(
189 "{}",
190 err
191 )))
192 }),
193 StatusCode::FORBIDDEN => {
194 Err(ConnpassCliError::HttpResponse(HttpResponseError::Forbidden))
195 }
196 StatusCode::INTERNAL_SERVER_ERROR => Err(ConnpassCliError::HttpResponse(
197 HttpResponseError::InternalServerError,
198 )),
199 StatusCode::SERVICE_UNAVAILABLE => Err(ConnpassCliError::HttpResponse(
200 HttpResponseError::ServiceUnavailable,
201 )),
202 s => Err(ConnpassCliError::HttpResponse(HttpResponseError::Various(
203 format!("Unexpected response received: {:?} (status code)", s),
204 ))),
205 }
206 }
207 }
208}