aboutsummaryrefslogtreecommitdiff
path: root/src/client.rs
diff options
context:
space:
mode:
authorHimbeerserverDE <himbeerserverde@gmail.com>2022-11-05 00:41:41 +0100
committerHimbeerserverDE <himbeerserverde@gmail.com>2022-11-05 00:41:41 +0100
commite5248adf8dc110b4f549d0b4af296deb765edb23 (patch)
treea8de224e177108e4bbb99edeefcb6a8c0dd81c4b /src/client.rs
parentacb34a49e82db411f4b348374b2e8d6c234728b3 (diff)
switch to custom serde_xmlrpc fork
closes #3
Diffstat (limited to 'src/client.rs')
-rw-r--r--src/client.rs74
1 files changed, 34 insertions, 40 deletions
diff --git a/src/client.rs b/src/client.rs
index 8aeb099..add352d 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -1,7 +1,6 @@
-use crate::{call, response};
+use crate::call::{self, Response};
use crate::{Error, Result};
-use std::collections::BTreeMap;
use std::sync::Arc;
use reqwest::{blocking, Url};
@@ -59,47 +58,42 @@ impl Client {
/// Issues a `Call` and returns a `Response`
/// if successful and if the status code
/// matches one of the expected status codes.
- pub fn call(&self, call: impl call::Call) -> Result<response::Response> {
+ pub fn call<T, U>(&self, call: T) -> Result<U>
+ where
+ T: call::Call + Response<U>,
+ U: serde::de::DeserializeOwned,
+ {
let expected = call.expected();
+ let xml = serde_xmlrpc::request_to_str(&call.method_name(), vec![call])?;
- let transport = self.inner.http.post::<Url>(self.inner.endpoint.into());
-
- let binding = call.method_name();
- let request = xmlrpc::Request::new(&binding).arg(call);
-
- let raw = request.call(transport)?;
- match raw {
- xmlrpc::Value::Struct(map) => {
- let code = map
- .get("code")
- .ok_or_else(|| Error::Inexistent("code".into()))?;
-
- match code {
- xmlrpc::Value::Int(code) => {
- if expected.contains(code) {
- let default = &xmlrpc::Value::Struct(BTreeMap::new());
- let data = map.get("resData").unwrap_or(default);
-
- match data {
- xmlrpc::Value::Struct(response) => Ok(response::Response {
- status: *code,
- data: response.clone(),
- }),
- _ => Err(Error::Type(
- "resData".into(),
- "Struct".into(),
- data.clone(),
- )),
- }
- } else {
- Err(Error::BadStatus(expected, *code))
- }
- }
- _ => Err(Error::Type("code".into(), "Int".into(), code.clone())),
- }
- }
- _ => Err(Error::BadResponse(raw.clone())),
+ let raw_response = self.inner.http.post::<Url>(self.inner.endpoint.into())
+ .body(xml)
+ .send()?
+ .text()?;
+
+ let map = serde_xmlrpc::value_from_str(&raw_response)?;
+
+ let resp = map
+ .as_struct()
+ .ok_or_else(|| Error::MalformedResponse(map.clone()))?;
+
+ let code = resp
+ .get("code")
+ .ok_or_else(|| Error::MalformedResponse(map.clone()))?
+ .as_i32()
+ .ok_or_else(|| Error::MalformedResponse(map.clone()))?;
+
+ if !expected.contains(&code) {
+ return Err(Error::BadStatus(expected, code));
}
+
+ let data = resp
+ .get("resData")
+ .ok_or_else(|| Error::MalformedResponse(map.clone()))?;
+
+ let res_data = serde_xmlrpc::value_to_string(data.clone())?;
+
+ Ok(serde_xmlrpc::response_from_str(&res_data)?)
}
}