aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeerserverDE <himbeerserverde@gmail.com>2022-10-21 19:10:36 +0200
committerHimbeerserverDE <himbeerserverde@gmail.com>2022-10-21 19:10:36 +0200
commitb346808516f3fe7d40ef389073a41583b32ef650 (patch)
treedf84273b217f5f80cf070993b2a84ae986264d8f
parent0fce2abca02faa831183c42b8e08e1766f5e6d74 (diff)
initial call/response structure
-rw-r--r--src/call/account.rs12
-rw-r--r--src/call/mod.rs6
-rw-r--r--src/client.rs62
-rw-r--r--src/lib.rs1
-rw-r--r--src/response/mod.rs7
5 files changed, 78 insertions, 10 deletions
diff --git a/src/call/account.rs b/src/call/account.rs
index f35ab00..865baf6 100644
--- a/src/call/account.rs
+++ b/src/call/account.rs
@@ -1,3 +1,5 @@
+use super::Call;
+
use std::collections::BTreeMap;
// Contains login information. Used to create an API session.
@@ -19,6 +21,11 @@ impl From<Login<'_>> for xmlrpc::Value {
}
}
+impl Call for Login<'_> {
+ fn method_name(&self) -> &'static str { "account.login" }
+ fn expected(&self) -> &'static [i32] { &[1000] }
+}
+
// Contains no information. This just signals to the server
// that it should end the session.
pub(crate) struct Logout;
@@ -28,3 +35,8 @@ impl From<Logout> for xmlrpc::Value {
xmlrpc::Value::Nil
}
}
+
+impl Call for Logout {
+ fn method_name(&self) -> &'static str { "account.logout" }
+ fn expected(&self) -> &'static [i32] { &[1500] }
+}
diff --git a/src/call/mod.rs b/src/call/mod.rs
index b0edc6c..83de339 100644
--- a/src/call/mod.rs
+++ b/src/call/mod.rs
@@ -1 +1,7 @@
+// A call to the API.
+pub trait Call: Into<xmlrpc::Value> {
+ fn method_name(&self) -> &'static str;
+ fn expected(&self) -> &'static [i32];
+}
+
pub mod account;
diff --git a/src/client.rs b/src/client.rs
index acb0760..a1047ff 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -1,8 +1,9 @@
+use crate::{call, response};
use crate::{Error, Result};
use std::sync::Arc;
-use reqwest::Url;
+use reqwest::{blocking, Url};
/// The INWX environment to use. The Sandbox is good for testing
/// or debugging purposes.
@@ -20,11 +21,9 @@ impl From<Endpoint> for &str {
}
}
-impl TryInto<Url> for Endpoint {
- type Error = Error;
- fn try_into(self) -> Result<Url> {
- let url = Url::parse(self.into())?;
- Ok(url)
+impl Into<Url> for Endpoint {
+ fn into(self) -> Url {
+ Url::parse(self.into()).unwrap()
}
}
@@ -41,11 +40,12 @@ impl Client {
pub fn login(ep: Endpoint, user: &str, pass: &str) -> Result<Client> {
let client = Client {
inner: Arc::new(ClientRef {
- http: reqwest::Client::builder().cookie_store(true).build()?,
+ http: blocking::Client::builder().cookie_store(true).build()?,
+ endpoint: ep,
}),
};
- client.call(crate::call::account::Login {
+ client.call(call::account::Login {
user,
pass,
case_insensitive: false,
@@ -53,15 +53,57 @@ impl Client {
Ok(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> {
+ let transport = self.inner.http.post(self.inner.endpoint.into());
+
+ let request = xmlrpc::Request::new(call.method_name());
+ request.arg(call);
+
+ let raw = request.call(transport)?;
+ match raw {
+ xmlrpc::Value::Struct(map) => {
+ let code = map.get("code")
+ .ok_or(Error::Inexistent("code"))?;
+
+ match code {
+ xmlrpc::Value::Int(code) => {
+ if call.expected().contains(code) {
+ let data = map.get("resData")
+ .ok_or(Error::Inexistent("resData"))?;
+
+ match data {
+ xmlrpc::Value::Struct(response) => {
+ Ok(response::Response {
+ status: *code,
+ data: response,
+ })
+ },
+ _ => Err(Error::Type("resData", "Struct")),
+ }
+ } else {
+ Err(Error::BadStatus(call.expected(), code))
+ }
+ },
+ _ => Err(Error::Type("code", "Int")),
+ }
+ },
+ _ => Err(Error::BadResponse(raw)),
+ }
+ }
}
impl Drop for Client {
fn drop(&mut self) {
- self.call(crate::call::account::Logout);
+ self.call(call::account::Logout);
}
}
// The underlying data of a `Client`.
struct ClientRef {
- http: reqwest::Client,
+ http: blocking::Client,
+ endpoint: Endpoint,
}
diff --git a/src/lib.rs b/src/lib.rs
index 13ad3f5..3f35d51 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,7 @@
pub mod call;
pub mod client;
pub mod error;
+pub mod response;
pub use client::Endpoint;
pub use error::{Error, Result};
diff --git a/src/response/mod.rs b/src/response/mod.rs
new file mode 100644
index 0000000..ddaa5f2
--- /dev/null
+++ b/src/response/mod.rs
@@ -0,0 +1,7 @@
+/// A Response to an API call including status and data.
+/// Data is guaranteed to be a `Struct`.
+/// [`Struct`]: xmlrpc::Value::Struct
+pub struct Response {
+ pub status: i32,
+ pub data: xmlrpc::Value,
+}