xml_rpc/
client.rs
1use super::error::{Result, ResultExt};
2use super::xmlfmt::{from_params, into_params, parse, Call, Fault, Params, Response};
3use hyper::{self, Client as HyperClient};
4use serde::{Deserialize, Serialize};
5use std;
6use Url;
7
8use hyper::header::Headers;
9header! { (ContentType, "ContentType") => [String] }
10
11pub fn call_value<Tkey>(uri: &Url, name: Tkey, params: Params) -> Result<Response>
12where
13 Tkey: Into<String>,
14{
15 Client::new()?.call_value(uri, name, params)
16}
17
18pub fn call<'a, Tkey, Treq, Tres>(
19 uri: &Url,
20 name: Tkey,
21 req: Treq,
22) -> Result<std::result::Result<Tres, Fault>>
23where
24 Tkey: Into<String>,
25 Treq: Serialize,
26 Tres: Deserialize<'a>,
27{
28 Client::new()?.call(uri, name, req)
29}
30
31pub struct Client {
32 client: HyperClient,
33}
34
35impl Client {
36 pub fn new() -> Result<Client> {
37 let client = HyperClient::new();
38 Ok(Client { client })
39 }
40
41 pub fn call_value<Tkey>(&mut self, uri: &Url, name: Tkey, params: Params) -> Result<Response>
42 where
43 Tkey: Into<String>,
44 {
45 use super::xmlfmt::value::ToXml;
46 let body_str = Call {
47 name: name.into(),
48 params,
49 }
50 .to_xml();
51 let bytes: &[u8] = body_str.as_bytes();
52 let body = hyper::client::Body::BufBody(bytes, bytes.len());
53
54 let mut headers = Headers::new();
55 headers.set(ContentType("xml".to_owned()));
56
57 let response = self
58 .client
59 .post(uri.as_ref())
60 .headers(headers)
61 .body(body)
62 .send()
63 .chain_err(|| "Failed to run the HTTP request within hyper.")?;
64
65 parse::response(response).map_err(Into::into)
66 }
67
68 pub fn call<'a, Tkey, Treq, Tres>(
69 &mut self,
70 uri: &Url,
71 name: Tkey,
72 req: Treq,
73 ) -> Result<std::result::Result<Tres, Fault>>
74 where
75 Tkey: Into<String>,
76 Treq: Serialize,
77 Tres: Deserialize<'a>,
78 {
79 match self.call_value(uri, name, into_params(&req)?) {
80 Ok(Ok(v)) => from_params(v).map(Ok).map_err(Into::into),
81 Ok(Err(v)) => Ok(Err(v)),
82 Err(v) => Err(v),
83 }
84 }
85}