#![cfg(feature = "digitalocean_droplets")]
#![allow(clippy::too_many_arguments, clippy::type_complexity)]
#![allow(clippy::missing_errors_doc, clippy::doc_markdown, clippy::useless_format)]
#![allow(unused_imports)]
use foundation_netio::{DynNetClient, PreparedRequestBuilder};
use foundation_netio::shared::client::http_client::HttpClient;
use serde::{Deserialize, Serialize};
use foundation_macros::JsonHash;
use super::shared::ApiResponse;
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct ActionLink {
pub href: Option<String>,
pub id: Option<i64>,
pub rel: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct AllDropletsResponse {
pub droplets: Option<Vec<Droplet>>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct DiskInfo {
pub size: Option<std::collections::HashMap<String, serde_json::Value>>,
#[serde(rename = "type")]
pub r#type: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct Droplet {
pub backup_ids: Vec<i64>,
pub created_at: String,
pub disk: i64,
pub disk_info: Option<Vec<DiskInfo>>,
pub features: Vec<String>,
pub gpu_info: Option<GpuInfo>,
pub id: i64,
pub image: serde_json::Value,
pub kernel: Option<Kernel>,
pub locked: bool,
pub memory: i64,
pub name: String,
pub networks: std::collections::HashMap<String, serde_json::Value>,
pub next_backup_window: serde_json::Value,
pub region: Region,
pub size: Size,
pub size_slug: String,
pub snapshot_ids: Vec<i64>,
pub status: String,
pub tags: Vec<String>,
pub vcpus: i64,
pub volume_ids: Vec<String>,
pub vpc_uuid: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct DropletCreate {
pub backup_policy: Option<serde_json::Value>,
pub backups: Option<bool>,
pub image: serde_json::Value,
pub ipv6: Option<bool>,
pub monitoring: Option<bool>,
pub private_networking: Option<bool>,
pub public_networking: Option<bool>,
pub region: Option<String>,
pub size: String,
pub ssh_keys: Option<Vec<serde_json::Value>>,
pub tags: Option<Vec<String>>,
pub user_data: Option<String>,
pub volumes: Option<Vec<String>>,
pub vpc_uuid: Option<String>,
pub with_droplet_agent: Option<bool>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct DropletCreateResponse {
#[serde(flatten)]
pub data: std::collections::HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct DropletMultiCreate {
pub names: Vec<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct DropletSingleCreate {
pub name: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct DropletsCreateRequest {
#[serde(flatten)]
pub data: std::collections::HashMap<String, serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct ExistingDropletResponse {
pub droplet: Option<Droplet>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct GpuInfo {
pub count: Option<i64>,
pub model: Option<String>,
pub vram: Option<std::collections::HashMap<String, serde_json::Value>>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct Kernel {
pub id: Option<i64>,
pub name: Option<String>,
pub version: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct Meta {
pub meta: serde_json::Value,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct NetworkV4 {
pub gateway: Option<String>,
pub ip_address: Option<String>,
pub netmask: Option<String>,
#[serde(rename = "type")]
pub r#type: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct NetworkV6 {
pub gateway: Option<String>,
pub ip_address: Option<String>,
pub netmask: Option<i64>,
#[serde(rename = "type")]
pub r#type: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct PageLinks {
pub pages: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct Pagination {
pub links: Option<PageLinks>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct Region {
pub available: bool,
pub features: Vec<String>,
pub name: String,
pub sizes: Vec<String>,
pub slug: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonHash)]
pub struct Size {
pub available: bool,
pub description: String,
pub disk: i64,
pub disk_info: Option<Vec<DiskInfo>>,
pub gpu_info: Option<GpuInfo>,
pub memory: i64,
pub price_hourly: f64,
pub price_monthly: f64,
pub regions: Vec<String>,
pub slug: String,
pub transfer: f64,
pub vcpus: i64,
}
#[derive(Debug, Clone, Default, Serialize, JsonHash)]
pub struct DropletsListArgs {
pub per_page: Option<String>,
pub page: Option<String>,
pub tag_name: Option<String>,
pub name: Option<String>,
pub r#type: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, JsonHash)]
pub struct DropletsCreateArgs {
pub body: DropletsCreateRequest,
}
#[derive(Debug, Clone, Default, Serialize, JsonHash)]
pub struct DropletsGetArgs {
pub droplet_id: String,
}
#[derive(Debug, Clone, Default, Serialize, JsonHash)]
pub struct DropletsDestroyArgs {
pub droplet_id: String,
}
pub async fn droplets_list_request<F>(
client: DynNetClient,
args: &DropletsListArgs,
base_url: &str,
builder_mod: Option<F>,
) -> Result<ApiResponse<AllDropletsResponse>, super::shared::ApiError>
where
F: FnOnce(&mut PreparedRequestBuilder),
{
let path = format!("/v2/droplets",
);
let endpoint_url = format!("{}{}", base_url, path);
let mut builder = PreparedRequestBuilder::get(&endpoint_url)
.map_err(|e| super::shared::ApiError::RequestBuildFailed(e.to_string()))?;
builder = builder.query("per_page", args.per_page.as_deref());
builder = builder.query("page", args.page.as_deref());
builder = builder.query("tag_name", args.tag_name.as_deref());
builder = builder.query("name", args.name.as_deref());
builder = builder.query("type", args.r#type.as_deref());
if let Some(f) = builder_mod {
f(&mut builder);
}
let response = client.send_async(builder.build()).await
.map_err(|e| super::shared::ApiError::RequestSendFailed(e.to_string()))?;
let status: usize = response.get_status().into();
let headers = response.get_headers_ref().clone();
if status < 200 || status >= 300 {
let error_bytes = foundation_netio::shared::client::body_reader::collect_bytes_from_send_safe(response.take_body());
let body = (!error_bytes.is_empty())
.then(|| String::from_utf8_lossy(&error_bytes).into_owned());
return Err(super::shared::ApiError::HttpStatus { code: status as u16, headers, body });
}
let body_bytes = foundation_netio::shared::client::body_reader::collect_bytes_from_send_safe(response.take_body());
let parsed: AllDropletsResponse = serde_json::from_slice(&body_bytes).map_err(|e: serde_json::Error| super::shared::ApiError::ParseFailed(e.to_string()))?;
Ok(ApiResponse { status: status as u16, headers, body: parsed })
}
pub async fn droplets_create_request<F>(
client: DynNetClient,
args: &DropletsCreateArgs,
base_url: &str,
builder_mod: Option<F>,
) -> Result<ApiResponse<DropletCreateResponse>, super::shared::ApiError>
where
F: FnOnce(&mut PreparedRequestBuilder),
{
let path = format!("/v2/droplets",
);
let endpoint_url = format!("{}{}", base_url, path);
let mut builder = PreparedRequestBuilder::post(&endpoint_url)
.map_err(|e| super::shared::ApiError::RequestBuildFailed(e.to_string()))?;
builder = builder.body_json(&args.body)
.map_err(|e| super::shared::ApiError::RequestBuildFailed(e.to_string()))?;
if let Some(f) = builder_mod {
f(&mut builder);
}
let response = client.send_async(builder.build()).await
.map_err(|e| super::shared::ApiError::RequestSendFailed(e.to_string()))?;
let status: usize = response.get_status().into();
let headers = response.get_headers_ref().clone();
if status < 200 || status >= 300 {
let error_bytes = foundation_netio::shared::client::body_reader::collect_bytes_from_send_safe(response.take_body());
let body = (!error_bytes.is_empty())
.then(|| String::from_utf8_lossy(&error_bytes).into_owned());
return Err(super::shared::ApiError::HttpStatus { code: status as u16, headers, body });
}
let body_bytes = foundation_netio::shared::client::body_reader::collect_bytes_from_send_safe(response.take_body());
let parsed: DropletCreateResponse = serde_json::from_slice(&body_bytes).map_err(|e: serde_json::Error| super::shared::ApiError::ParseFailed(e.to_string()))?;
Ok(ApiResponse { status: status as u16, headers, body: parsed })
}
pub async fn droplets_get_request<F>(
client: DynNetClient,
args: &DropletsGetArgs,
base_url: &str,
builder_mod: Option<F>,
) -> Result<ApiResponse<ExistingDropletResponse>, super::shared::ApiError>
where
F: FnOnce(&mut PreparedRequestBuilder),
{
let path = format!("/v2/droplets/{}",
args.droplet_id,
);
let endpoint_url = format!("{}{}", base_url, path);
let mut builder = PreparedRequestBuilder::get(&endpoint_url)
.map_err(|e| super::shared::ApiError::RequestBuildFailed(e.to_string()))?;
if let Some(f) = builder_mod {
f(&mut builder);
}
let response = client.send_async(builder.build()).await
.map_err(|e| super::shared::ApiError::RequestSendFailed(e.to_string()))?;
let status: usize = response.get_status().into();
let headers = response.get_headers_ref().clone();
if status < 200 || status >= 300 {
let error_bytes = foundation_netio::shared::client::body_reader::collect_bytes_from_send_safe(response.take_body());
let body = (!error_bytes.is_empty())
.then(|| String::from_utf8_lossy(&error_bytes).into_owned());
return Err(super::shared::ApiError::HttpStatus { code: status as u16, headers, body });
}
let body_bytes = foundation_netio::shared::client::body_reader::collect_bytes_from_send_safe(response.take_body());
let parsed: ExistingDropletResponse = serde_json::from_slice(&body_bytes).map_err(|e: serde_json::Error| super::shared::ApiError::ParseFailed(e.to_string()))?;
Ok(ApiResponse { status: status as u16, headers, body: parsed })
}
pub async fn droplets_destroy_request<F>(
client: DynNetClient,
args: &DropletsDestroyArgs,
base_url: &str,
builder_mod: Option<F>,
) -> Result<ApiResponse<()>, super::shared::ApiError>
where
F: FnOnce(&mut PreparedRequestBuilder),
{
let path = format!("/v2/droplets/{}",
args.droplet_id,
);
let endpoint_url = format!("{}{}", base_url, path);
let mut builder = PreparedRequestBuilder::delete(&endpoint_url)
.map_err(|e| super::shared::ApiError::RequestBuildFailed(e.to_string()))?;
if let Some(f) = builder_mod {
f(&mut builder);
}
let response = client.send_async(builder.build()).await
.map_err(|e| super::shared::ApiError::RequestSendFailed(e.to_string()))?;
let status: usize = response.get_status().into();
let headers = response.get_headers_ref().clone();
if status < 200 || status >= 300 {
let error_bytes = foundation_netio::shared::client::body_reader::collect_bytes_from_send_safe(response.take_body());
let body = (!error_bytes.is_empty())
.then(|| String::from_utf8_lossy(&error_bytes).into_owned());
return Err(super::shared::ApiError::HttpStatus { code: status as u16, headers, body });
}
Ok(ApiResponse { status: status as u16, headers, body: () })
}