use self::droplet_fields::{Kernel, Networks, NextBackupWindow};
use super::snapshot::Snapshot;
use super::{ApiLinks, ApiMeta};
use super::{HasPagination, HasResponse, HasValue};
use super::{Image, Region, Size};
use crate::method::{Create, Delete, Get, List};
use crate::request::Request;
use crate::request::{DropletRequest, SnapshotRequest};
use crate::{ROOT_URL, STATIC_URL_ERROR};
use chrono::{DateTime, Utc};
use getset::{Getters, Setters};
use serde::Serialize;
use std::fmt::Display;
use url::Url;
const DROPLETS_SEGMENT: &str = "droplets";
const REPORTS_SEGMENT: &str = "reports";
const DROPLET_NEIGHBORS_SEGMENT: &str = "droplet_neighbors";
const NEIGHBORS_SEGMENT: &str = "neighbors";
const SNAPSHOTS_SEGMENT: &str = "snapshots";
const BACKUPS_SEGMENT: &str = "backups";
#[derive(Deserialize, Serialize, Debug, Clone, Getters, Setters)]
#[get = "pub"]
pub struct Droplet {
id: usize,
name: String,
memory: usize,
vcpus: usize,
disk: usize,
locked: bool,
created_at: DateTime<Utc>,
status: String,
backup_ids: Vec<usize>,
snapshot_ids: Vec<usize>,
features: Vec<String>,
region: Region,
image: Image,
size: Size,
size_slug: String,
networks: Networks,
kernel: Option<Kernel>,
next_backup_window: Option<NextBackupWindow>,
tags: Vec<String>,
volume_ids: Vec<String>
}
pub mod droplet_fields {
use chrono::{DateTime, Utc};
use std::net::{Ipv4Addr, Ipv6Addr};
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Networks {
pub v4: Vec<NetworkV4>,
pub v6: Vec<NetworkV6>
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct NetworkV4 {
pub gateway: Ipv4Addr,
pub ip_address: Ipv4Addr,
pub netmask: Ipv4Addr,
#[serde(rename = "type")]
pub kind: String
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct NetworkV6 {
pub gateway: Ipv6Addr,
pub ip_address: Ipv6Addr,
pub netmask: usize,
#[serde(rename = "type")]
pub kind: String
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct NextBackupWindow {
pub end: DateTime<Utc>,
pub start: DateTime<Utc>
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Kernel {
pub id: usize,
pub name: String,
pub version: String
}
}
impl Droplet {
pub fn create<S, D>(name: S, region: S, size: S, image: D) -> DropletRequest<Create, Droplet>
where
S: AsRef<str> + Serialize + Display,
D: Serialize + Display {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(DROPLETS_SEGMENT);
let mut req = Request::new(url);
req.set_body(json!({
"name": name,
"region": region,
"size": size,
"image": format!("{}", image),
}));
req
}
pub fn create_multiple<S, D>(
names: Vec<S>,
region: S,
size: S,
image: D,
) -> DropletRequest<Create, Vec<Droplet>>
where
S: AsRef<str> + Serialize + Display,
D: Serialize + Display {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(DROPLETS_SEGMENT);
let mut req = Request::new(url);
req.set_body(json!({
"names": names,
"region": region,
"size": size,
"image": format!("{}", image),
}));
req
}
pub fn get(id: usize) -> DropletRequest<Get, Droplet> {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(DROPLETS_SEGMENT)
.push(&id.to_string());
Request::new(url)
}
pub fn list() -> DropletRequest<List, Vec<Droplet>> {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(DROPLETS_SEGMENT);
Request::new(url)
}
pub fn list_by_tag<S: AsRef<str> + Serialize>(name: S) -> DropletRequest<List, Vec<Droplet>> {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(DROPLETS_SEGMENT);
url.query_pairs_mut().append_pair("tag_name", name.as_ref());
Request::new(url)
}
pub fn delete(id: usize) -> DropletRequest<Delete, ()> {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(DROPLETS_SEGMENT)
.push(&id.to_string());
Request::new(url)
}
pub fn delete_by_tag<S: AsRef<str> + Serialize>(name: S) -> DropletRequest<Delete, ()> {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(DROPLETS_SEGMENT);
url.query_pairs_mut().append_pair("tag_name", name.as_ref());
Request::new(url)
}
pub fn neighbors() -> DropletRequest<Get, Vec<Vec<Droplet>>> {
let mut url = ROOT_URL.clone();
url.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(REPORTS_SEGMENT)
.push(DROPLET_NEIGHBORS_SEGMENT);
Request::new(url)
}
}
impl DropletRequest<Create, Droplet> {
pub fn ssh_keys<D>(mut self, val: Vec<D>) -> Self
where
D: Display + Serialize,
{
self.body_mut()["ssh_keys"] = json!(val);
self
}
pub fn backups(mut self, val: bool) -> Self {
self.body_mut()["backups"] = json!(val);
self
}
pub fn ipv6(mut self, val: bool) -> Self {
self.body_mut()["ipv6"] = json!(val);
self
}
pub fn private_networking(mut self, val: bool) -> Self {
self.body_mut()["private_networking"] = json!(val);
self
}
pub fn user_data(mut self, val: bool) -> Self {
self.body_mut()["user_data"] = json!(val);
self
}
pub fn monitoring(mut self, val: bool) -> Self {
self.body_mut()["monitoring"] = json!(val);
self
}
pub fn volumes(mut self, val: Vec<String>) -> Self {
self.body_mut()["volumes"] = json!(val);
self
}
pub fn tags(mut self, val: Vec<String>) -> Self {
self.body_mut()["tags"] = json!(val);
self
}
}
impl DropletRequest<Create, Vec<Droplet>> {
pub fn ssh_keys<D>(mut self, val: Vec<D>) -> Self
where
D: Display + Serialize,
{
self.body_mut()["ssh_keys"] = json!(val);
self
}
pub fn backups(mut self, val: bool) -> Self {
self.body_mut()["backups"] = json!(val);
self
}
pub fn ipv6(mut self, val: bool) -> Self {
self.body_mut()["ipv6"] = json!(val);
self
}
pub fn private_networking(mut self, val: bool) -> Self {
self.body_mut()["private_networking"] = json!(val);
self
}
pub fn user_data(mut self, val: bool) -> Self {
self.body_mut()["user_data"] = json!(val);
self
}
pub fn monitoring(mut self, val: bool) -> Self {
self.body_mut()["monitoring"] = json!(val);
self
}
pub fn volumes(mut self, val: Vec<String>) -> Self {
self.body_mut()["volumes"] = json!(val);
self
}
pub fn tags(mut self, val: Vec<String>) -> Self {
self.body_mut()["tags"] = json!(val);
self
}
}
impl DropletRequest<Get, Droplet> {
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 backups(mut self) -> SnapshotRequest<List, Vec<Snapshot>> {
self.url_mut()
.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(BACKUPS_SEGMENT);
self.transmute()
}
pub fn neighbors(mut self) -> DropletRequest<List, Vec<Droplet>> {
self.url_mut()
.path_segments_mut()
.expect(STATIC_URL_ERROR)
.push(NEIGHBORS_SEGMENT);
self.transmute()
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct DropletResponse {
droplet: Droplet
}
impl HasResponse for Droplet {
type Response = DropletResponse;
}
impl HasValue for DropletResponse {
type Value = Droplet;
fn value(self) -> Droplet {
self.droplet
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct DropletListResponse {
droplets: Vec<Droplet>,
links: ApiLinks,
meta: ApiMeta
}
impl HasResponse for Vec<Droplet> {
type Response = DropletListResponse;
}
impl HasPagination for DropletListResponse {
fn next_page(&self) -> Option<Url> {
self.links.next()
}
}
impl HasValue for DropletListResponse {
type Value = Vec<Droplet>;
fn value(self) -> Vec<Droplet> {
self.droplets
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct DropletNeighborsResponse {
neighbors: Vec<Vec<Droplet>>
}
impl HasResponse for Vec<Vec<Droplet>> {
type Response = DropletNeighborsResponse;
}
impl HasValue for DropletNeighborsResponse {
type Value = Vec<Vec<Droplet>>;
fn value(self) -> Vec<Vec<Droplet>> {
self.neighbors
}
}