Compare commits
No commits in common. "66fa21f50f669abc28fb145f4c1c830040324abc" and "9f97a2cae3ffdf95b6a762ecce7ff0a47142b902" have entirely different histories.
66fa21f50f
...
9f97a2cae3
1 changed files with 32 additions and 43 deletions
|
@ -7,6 +7,15 @@ fn runtime() -> &'static tokio::runtime::Runtime {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> schema::SubsonicResponse<T> {
|
||||||
|
fn fixup(self) -> Result<T, Error> {
|
||||||
|
match self {
|
||||||
|
Self::Ok { inner } => Ok(inner),
|
||||||
|
Self::Failed { error } => Err(Error::SubsonicError(error)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
UrlParseError(url::ParseError),
|
UrlParseError(url::ParseError),
|
||||||
|
@ -87,48 +96,7 @@ impl Client {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send<T: serde::de::DeserializeOwned + Send + 'static>(
|
async fn get<T: serde::de::DeserializeOwned>(
|
||||||
&self,
|
|
||||||
request: reqwest::RequestBuilder,
|
|
||||||
) -> Result<T, Error> {
|
|
||||||
// FIXME: is an entire channel per request overkill? maybe pool them?
|
|
||||||
let (sender, receiver) = async_channel::bounded(1);
|
|
||||||
|
|
||||||
// let tokio take care of the request + further json parsing
|
|
||||||
// this is because reqwest doesn't like the glib main loop
|
|
||||||
// note that this is why those silly bounds on T are needed, because we're
|
|
||||||
// sending back the result of the query from another thread
|
|
||||||
let future = request.send();
|
|
||||||
runtime().spawn(async move {
|
|
||||||
// wrap this logic in a fn so we can use ?
|
|
||||||
async fn perform<T: serde::de::DeserializeOwned + Send + 'static>(
|
|
||||||
response: Result<reqwest::Response, reqwest::Error>,
|
|
||||||
) -> Result<schema::SubsonicResponse<T>, reqwest::Error> {
|
|
||||||
Ok(response?
|
|
||||||
.error_for_status()?
|
|
||||||
.json::<schema::SubsonicResponseOuter<T>>()
|
|
||||||
.await?
|
|
||||||
.subsonic_response)
|
|
||||||
}
|
|
||||||
|
|
||||||
sender
|
|
||||||
.send(perform(future.await).await)
|
|
||||||
.await
|
|
||||||
.expect("could not send subsonic response back to the main loop");
|
|
||||||
});
|
|
||||||
|
|
||||||
let response = receiver
|
|
||||||
.recv()
|
|
||||||
.await
|
|
||||||
.expect("could not receive subsonic response from tokio")?;
|
|
||||||
|
|
||||||
match response {
|
|
||||||
schema::SubsonicResponse::Ok { inner } => Ok(inner),
|
|
||||||
schema::SubsonicResponse::Failed { error } => Err(Error::SubsonicError(error)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get<T: serde::de::DeserializeOwned + Send + 'static>(
|
|
||||||
&self,
|
&self,
|
||||||
path: &[&str],
|
path: &[&str],
|
||||||
query: &[(&str, &str)],
|
query: &[(&str, &str)],
|
||||||
|
@ -138,7 +106,28 @@ impl Client {
|
||||||
// literally can't fail
|
// literally can't fail
|
||||||
.unwrap_or_else(|_| unsafe { std::hint::unreachable_unchecked() })
|
.unwrap_or_else(|_| unsafe { std::hint::unreachable_unchecked() })
|
||||||
.extend(path);
|
.extend(path);
|
||||||
self.send(self.client.get(url).query(query)).await
|
|
||||||
|
// FIXME: is an entire channel per request overkill? maybe pool them?
|
||||||
|
let (sender, receiver) = async_channel::bounded(1);
|
||||||
|
|
||||||
|
let future = self.client.get(url).query(query).send();
|
||||||
|
runtime().spawn(async move {
|
||||||
|
let response = future.await;
|
||||||
|
sender
|
||||||
|
.send(response)
|
||||||
|
.await
|
||||||
|
.expect("could not send subsonic response back to the main loop");
|
||||||
|
});
|
||||||
|
|
||||||
|
receiver
|
||||||
|
.recv()
|
||||||
|
.await
|
||||||
|
.expect("could not receive subsonic response from tokio")?
|
||||||
|
.error_for_status()?
|
||||||
|
.json::<schema::SubsonicResponseOuter<T>>()
|
||||||
|
.await?
|
||||||
|
.subsonic_response
|
||||||
|
.fixup()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn ping(&self) -> Result<(), Error> {
|
pub async fn ping(&self) -> Result<(), Error> {
|
||||||
|
|
Loading…
Reference in a new issue