use super::{ApiLinks, ApiMeta};
use super::{HasPagination, HasResponse, HasValue};
use super::region::Region;
use super::snapshot::Snapshot;
use {ROOT_URL, STATIC_URL_ERROR};
use chrono::{DateTime, Utc};
use method::{Create, Delete, Get, List};
use request::{SnapshotRequest, VolumeRequest};
use request::Request;
use serde::Serialize;
use std::fmt::Display;
use url::Url;
const VOLUME_SEGMENT: &'static str = "volumes";
const SNAPSHOTS_SEGMENT: &'static str = "snapshots";
#[derive(Deserialize, Serialize, Debug, Clone, Getters, Setters)]
pub struct Volume {
#[get = "pub"]
id: String,
#[get = "pub"]
region: Region,
#[get = "pub"]
droplet_ids: Vec<usize>,
#[get = "pub"]
name: String,
#[get = "pub"]
description: String,
#[get = "pub"]
size_gigabytes: usize,
#[get = "pub"]
created_at: DateTime<Utc>,
}
impl Volume {
pub fn list() -> VolumeRequest<List, Vec<Volume>> {
let mut url = ROOT_URL.clone();
url.path_segments_mut().expect(STATIC_URL_ERROR).push(
VOLUME_SEGMENT,
);
Request::new(url)
}
pub fn create<S>(name: S, size_gigabytes: usize) -> VolumeRequest<Create, Volume>
where
S: AsRef<str> + Serialize + Display,
{
let mut url = ROOT_URL.clone();
url.path_segments_mut().expect(STATIC_URL_ERROR).push(
VOLUME_SEGMENT,
);
let mut req = Request::new(url);
req.set_body(json!({
"name": name,
"size_gigabytes": size_gigabytes,
}));
req
}
pub fn get<S>(id: S) -> VolumeRequest<Get, Volume>
where
S: AsRef<str> + Serialize + Display,
{
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(VOLUME_SEGMENT)
.push(id.as_ref());
Request::new(url)
}
pub fn get_by_name<S>(name: S, region: S) -> VolumeRequest<Get, Volume>
where
S: AsRef<str> + Serialize + Display,
{
let mut url = ROOT_URL.clone();
url.path_segments_mut().expect(STATIC_URL_ERROR).push(
VOLUME_SEGMENT,
);
url.query_pairs_mut()
.append_pair("name", name.as_ref())
.append_pair("region", region.as_ref());
Request::new(url)
}
pub fn delete<S>(id: S) -> VolumeRequest<Delete, ()>
where
S: AsRef<str> + Serialize + Display,
{
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(VOLUME_SEGMENT)
.push(id.as_ref());
Request::new(url)
}
pub fn delete_by_name<S>(name: S, region: S) -> VolumeRequest<Delete, ()>
where
S: AsRef<str> + Serialize + Display,
{
let mut url = ROOT_URL.clone();
url.path_segments_mut().expect(STATIC_URL_ERROR).push(
VOLUME_SEGMENT,
);
url.query_pairs_mut()
.append_pair("name", name.as_ref())
.append_pair("region", region.as_ref());
Request::new(url)
}
}
impl VolumeRequest<List, Vec<Volume>> {
pub fn region<S>(mut self, region: S) -> Self
where
S: AsRef<str> + Serialize + Display,
{
self.url_mut().query_pairs_mut().append_pair(
"region",
region.as_ref(),
);
self
}
}
impl VolumeRequest<Get, Volume> {
pub fn snapshots(mut self) -> SnapshotRequest<List, Vec<Snapshot>> {
self.url_mut()
.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(SNAPSHOTS_SEGMENT);
self.transmute()
}
pub fn snapshot<S>(mut self, name: S) -> SnapshotRequest<Create, Snapshot>
where
S: AsRef<str> + Serialize + Display,
{
self.url_mut()
.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(SNAPSHOTS_SEGMENT);
self.set_body(json!({
"name": name
}));
self.transmute()
}
}
impl VolumeRequest<Create, Volume> {
pub fn description<S>(mut self, val: S) -> Self
where
S: AsRef<str> + Serialize + Display,
{
self.body_mut()["description"] = json!(val);
self
}
pub fn region<S>(mut self, val: S) -> Self
where
S: AsRef<str> + Serialize + Display,
{
self.body_mut()["region"] = json!(val);
self
}
pub fn snapshot_id<S>(mut self, val: S) -> Self
where
S: AsRef<str> + Serialize + Display,
{
self.body_mut()["snapshot_id"] = json!(val);
self
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct VolumeListResponse {
volumes: Vec<Volume>,
links: ApiLinks,
meta: ApiMeta,
}
impl HasResponse for Vec<Volume> {
type Response = VolumeListResponse;
}
impl HasPagination for VolumeListResponse {
fn next_page(&self) -> Option<Url> {
self.links.next()
}
}
impl HasValue for VolumeListResponse {
type Value = Vec<Volume>;
fn value(self) -> Vec<Volume> {
self.volumes
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct VolumeResponse {
volume: Volume,
}
impl HasResponse for Volume {
type Response = VolumeResponse;
}
impl HasValue for VolumeResponse {
type Value = Volume;
fn value(self) -> Volume {
self.volume
}
}