use DigitalOcean;
use api::{HasPagination, HasResponse};
use error::*;
use method::{Create, Delete, Get, List, Method, Update};
use serde_json::Value;
use std::marker::PhantomData;
use url::Url;
use url_serde;
pub type AccountRequest<M, V> = Request<M, V>;
pub type ActionRequest<M, V> = Request<M, V>;
pub type CertificateRequest<M, V> = Request<M, V>;
pub type DomainRecordRequest<M, V> = Request<M, V>;
pub type DomainRequest<M, V> = Request<M, V>;
pub type DropletActionRequest<M, V> = Request<M, V>;
pub type DropletRequest<M, V> = Request<M, V>;
pub type FloatingIpActionRequest<M, V> = Request<M, V>;
pub type FloatingIpRequest<M, V> = Request<M, V>;
pub type ImageActionRequest<M, V> = Request<M, V>;
pub type ImageRequest<M, V> = Request<M, V>;
pub type LoadBalancerRequest<M, V> = Request<M, V>;
pub type RegionRequest<M, V> = Request<M, V>;
pub type SizeRequest<M, V> = Request<M, V>;
pub type SnapshotRequest<M, V> = Request<M, V>;
pub type SshKeyRequest<M, V> = Request<M, V>;
pub type TagRequest<M, V> = Request<M, V>;
pub type VolumeActionRequest<M, V> = Request<M, V>;
pub type VolumeRequest<M, V> = Request<M, V>;
#[derive(Debug, Clone, Serialize, Deserialize, MutGetters, Getters, Setters)]
pub struct Request<A, R>
where
A: Method,
{
#[get_mut = "pub"]
#[set = "pub"]
#[get = "pub"]
#[serde(with = "url_serde")]
url: Url,
#[get_mut = "pub"]
#[set = "pub"]
#[get = "pub"]
body: Value,
#[get = "pub"]
method: A,
value: PhantomData<R>,
}
impl<A, V> Request<A, V>
where
A: Method,
{
pub fn new(url: Url) -> Self {
Request {
url: url,
body: Value::Null,
method: A::default(),
value: PhantomData,
}
}
pub(crate) fn transmute<C, D>(self) -> Request<C, D>
where
C: Method,
{
let mut req = Request::new(self.url);
req.set_body(self.body);
req
}
}
impl<V> Request<List, V> {
pub fn limit(mut self, limit: Option<usize>) -> Self {
self.method.0 = limit;
self
}
}
pub trait Executable<T>: Sized
where
T: HasResponse,
{
fn execute(self, instance: &DigitalOcean) -> Result<T>;
}
impl<V> Executable<Vec<V>> for Request<List, Vec<V>>
where
Vec<V>: HasResponse,
<Vec<V> as HasResponse>::Response: HasPagination,
{
fn execute(self, instance: &DigitalOcean) -> Result<Vec<V>> {
let response: Vec<V> = instance.list(self)?;
Ok(response)
}
}
impl<V> Executable<V> for Request<Create, V>
where
V: HasResponse,
{
fn execute(self, instance: &DigitalOcean) -> Result<V> {
let response = instance.post(self)?;
Ok(response)
}
}
impl<V> Executable<V> for Request<Update, V>
where
V: HasResponse,
{
fn execute(self, instance: &DigitalOcean) -> Result<V> {
let response = instance.put(self)?;
Ok(response)
}
}
impl<V> Executable<V> for Request<Get, V>
where
V: HasResponse,
{
fn execute(self, instance: &DigitalOcean) -> Result<V> {
let response = instance.get(self)?;
Ok(response)
}
}
impl Executable<()> for Request<Delete, ()> {
fn execute(self, instance: &DigitalOcean) -> Result<()> {
let response = instance.delete(self)?;
Ok(response)
}
}