use std::sync::Arc;
use serde::{Deserialize, Serialize};
use serde_json as json;
use super::{ip::Ip, os::Os};
use crate::client::Client;
#[derive(Debug)]
pub struct Plan {
client: Arc<Client>,
}
impl Plan {
pub fn new(client: Arc<Client>) -> Self {
Self { client }
}
pub async fn list_vm(&self) -> Result<Vec<PlanResource>, crate::Error> {
let response = self.client.get("/products").await?;
let response: Vec<PlanResource> = json::from_value(response)?;
Ok(response)
}
pub async fn get_vm(&self, id: u32) -> Result<PlanResource, crate::Error> {
let response = self.client.get(&format!("/products/{id}")).await?;
let response: PlanResource = json::from_value(response)?;
let response = response.with_client(Arc::clone(&self.client));
Ok(response)
}
pub async fn list_snapshot(&self) -> Result<Vec<PlanResource>, crate::Error> {
let response = self.client.get("/snapshots/products").await?;
let response: Vec<PlanResource> = json::from_value(response)?;
Ok(response)
}
pub async fn get_snapshot(&self, id: u32) -> Result<PlanResource, crate::Error> {
let response = self
.client
.get(&format!("/snapshots/products/{id}"))
.await?;
let response: PlanResource = json::from_value(response)?;
Ok(response)
}
}
#[derive(Debug, Deserialize, Serialize)]
pub struct PlanResource {
#[serde(rename = "product_id")]
pub id: u32,
pub name: String,
pub description: String,
pub category_id: u32,
pub category_name: String,
pub options: Options,
pub billing: Vec<Billing>,
#[serde(skip)]
client: Arc<Client>,
}
impl PlanResource {
fn with_client(mut self, client: Arc<Client>) -> Self {
self.client = client;
self
}
pub async fn os(&self) -> Result<Os, crate::Error> {
let os = Os::new(Arc::clone(&self.client), self.id);
Ok(os)
}
pub async fn ip(&self) -> Result<Ip, crate::Error> {
let ip = Ip::new(Arc::clone(&self.client), self.id);
Ok(ip)
}
pub async fn get_billing(&self, label: &str) -> Result<Billing, crate::Error> {
for billing in &self.billing {
if billing.label == label {
return Ok(billing.clone());
}
}
Err(crate::Error::NotFound("Billing is not found".to_string()))
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Billing {
pub label: String,
pub cycle: String,
pub price: u32,
pub components: Option<Vec<Component>>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Component {
pub label: String,
pub field: String,
pub prices: Vec<Price>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Price {
pub qty_min: i32,
pub qty_max: i32,
pub price: u32,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct Options {
#[serde(rename = "type")]
pub r#type: String,
pub cores: u32,
pub memory: u32,
pub allow_downgrade: i32,
}