diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2022-11-05 00:41:41 +0100 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2022-11-05 00:41:41 +0100 |
commit | e5248adf8dc110b4f549d0b4af296deb765edb23 (patch) | |
tree | a8de224e177108e4bbb99edeefcb6a8c0dd81c4b /src/client.rs | |
parent | acb34a49e82db411f4b348374b2e8d6c234728b3 (diff) |
switch to custom serde_xmlrpc fork
closes #3
Diffstat (limited to 'src/client.rs')
-rw-r--r-- | src/client.rs | 74 |
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)?) } } |