Skip to content

Commit e2d98bf

Browse files
committed
Update client to return full HTTP request/response context instead of just response body
1 parent 810c52c commit e2d98bf

File tree

2 files changed

+40
-18
lines changed

2 files changed

+40
-18
lines changed

examples/sample/src/main.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ async fn main() {
66
let api_key = None;
77

88
// Create client
9-
let client = podcast_api::Client::new(reqwest::Client::new(), api_key);
9+
let client = podcast_api::Client::new(api_key);
1010

1111
// Call API
1212
match client
@@ -18,8 +18,12 @@ async fn main() {
1818
{
1919
Ok(response) => {
2020
println!("Successfully called \"typeahead\" endpoint.");
21-
println!("Response Body:");
22-
println!("{:?}", response);
21+
if let Ok(body) = response.json().await {
22+
println!("Response Body:");
23+
println!("{:?}", body);
24+
} else {
25+
println!("Response body JSON data parsing error.")
26+
}
2327
}
2428
Err(err) => {
2529
println!("Error calling \"typeahead\" endpoint:");

src/client.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ pub struct Client<'a> {
1515
user_agent: &'a str,
1616
}
1717

18+
#[derive(Debug)]
19+
/// Response and request context for API call.
20+
pub struct Response {
21+
/// HTTP response.
22+
pub response: reqwest::Response,
23+
/// HTTP request that resulted in this response.
24+
pub request: reqwest::Request,
25+
}
26+
27+
impl Response {
28+
/// Get JSON data object from [`reqwest::Response`].
29+
pub async fn json(self) -> Result<Value> {
30+
Ok(self.response.json().await?)
31+
}
32+
}
33+
1834
impl Client<'_> {
1935
/// Creates new Listen API Client.
2036
///
@@ -65,41 +81,41 @@ impl Client<'_> {
6581
}
6682

6783
/// Calls [`GET /search`](https://www.listennotes.com/api/docs/#get-api-v2-search) with supplied parameters.
68-
pub async fn search(&self, parameters: &Value) -> Result<Value> {
84+
pub async fn search(&self, parameters: &Value) -> Result<Response> {
6985
self.get("search", parameters).await
7086
}
7187

7288
/// Calls [`GET /typeahead`](https://www.listennotes.com/api/docs/#get-api-v2-typeahead) with supplied parameters.
73-
pub async fn typeahead(&self, parameters: &Value) -> Result<Value> {
89+
pub async fn typeahead(&self, parameters: &Value) -> Result<Response> {
7490
self.get("typeahead", parameters).await
7591
}
7692

7793
/// Calls [`GET /best_podcasts`](https://www.listennotes.com/api/docs/#get-api-v2-best_podcasts) with supplied parameters.
78-
pub async fn fetch_best_podcasts(&self, parameters: &Value) -> Result<Value> {
94+
pub async fn fetch_best_podcasts(&self, parameters: &Value) -> Result<Response> {
7995
self.get("best_podcasts", parameters).await
8096
}
8197

8298
/// Calls [`GET /podcasts/{id}`](https://www.listennotes.com/api/docs/#get-api-v2-podcasts-id) with supplied parameters.
83-
pub async fn fetch_podcast_by_id(&self, id: &str, parameters: &Value) -> Result<Value> {
99+
pub async fn fetch_podcast_by_id(&self, id: &str, parameters: &Value) -> Result<Response> {
84100
self.get(&format!("podcasts/{}", id), parameters).await
85101
}
86102

87103
/// Calls [`POST /podcasts`](https://www.listennotes.com/api/docs/#post-api-v2-podcasts) with supplied parameters.
88-
pub async fn batch_fetch_podcasts(&self, parameters: &Value) -> Result<Value> {
104+
pub async fn batch_fetch_podcasts(&self, parameters: &Value) -> Result<Response> {
89105
self.post("podcasts", parameters).await
90106
}
91107

92108
/// Calls [`GET /episodes/{id}`](https://www.listennotes.com/api/docs/#get-api-v2-episodes-id) with supplied parameters.
93-
pub async fn fetch_episode_by_id(&self, id: &str, parameters: &Value) -> Result<Value> {
109+
pub async fn fetch_episode_by_id(&self, id: &str, parameters: &Value) -> Result<Response> {
94110
self.get(&format!("episodes/{}", id), parameters).await
95111
}
96112

97113
/// Calls [`POST /episodes`](https://www.listennotes.com/api/docs/#post-api-v2-episodes) with supplied parameters.
98-
pub async fn batch_fetch_episodes(&self, parameters: &Value) -> Result<Value> {
114+
pub async fn batch_fetch_episodes(&self, parameters: &Value) -> Result<Response> {
99115
self.post("episodes", parameters).await
100116
}
101117

102-
async fn get(&self, endpoint: &str, parameters: &Value) -> Result<Value> {
118+
async fn get(&self, endpoint: &str, parameters: &Value) -> Result<Response> {
103119
let request = self
104120
.client
105121
.get(format!("{}/{}", self.api.url(), endpoint))
@@ -108,7 +124,7 @@ impl Client<'_> {
108124
Ok(self.request(request).await?)
109125
}
110126

111-
async fn post(&self, endpoint: &str, parameters: &Value) -> Result<Value> {
127+
async fn post(&self, endpoint: &str, parameters: &Value) -> Result<Response> {
112128
let request = self
113129
.client
114130
.post(format!("{}/{}", self.api.url(), endpoint))
@@ -118,17 +134,19 @@ impl Client<'_> {
118134
Ok(self.request(request).await?)
119135
}
120136

121-
async fn request(&self, request: RequestBuilder) -> Result<Value> {
122-
Ok(if let Api::Production(key) = self.api {
137+
async fn request(&self, request: RequestBuilder) -> Result<Response> {
138+
let request = if let Api::Production(key) = self.api {
123139
request.header("X-ListenAPI-Key", key)
124140
} else {
125141
request
126142
}
127143
.header("User-Agent", self.user_agent)
128-
.send()
129-
.await?
130-
.json()
131-
.await?)
144+
.build()?;
145+
146+
Ok(Response {
147+
response: self.client.execute(request.try_clone().expect("Error can remain unhandled because we're not using streams, which are the try_clone fail condition")).await?,
148+
request,
149+
})
132150
}
133151

134152
fn urlencoded_from_json(json: &Value) -> String {

0 commit comments

Comments
 (0)