use bytesize::ByteSize;
use serde::{Deserialize, Serialize};
use std::{
fmt::Display,
net::{IpAddr, Ipv4Addr, Ipv6Addr},
};
use time::Date;
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ServerId(pub u32);
impl From<u32> for ServerId {
fn from(value: u32) -> Self {
ServerId(value)
}
}
impl From<ServerId> for u32 {
fn from(value: ServerId) -> Self {
value.0
}
}
impl Display for ServerId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl PartialEq<u32> for ServerId {
fn eq(&self, other: &u32) -> bool {
self.0.eq(other)
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum Status {
#[serde(rename = "ready")]
Ready,
#[serde(rename = "in progress")]
InProgress,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct SubnetReference {
#[serde(rename = "ip")]
pub ip: IpAddr,
pub mask: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct ServerFlags {
pub reset: bool,
pub rescue: bool,
pub vnc: bool,
pub windows: bool,
pub plesk: bool,
pub cpanel: bool,
pub wol: bool,
pub hot_swap: bool,
pub linked_storagebox: Option<u32>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Server {
#[serde(rename = "server_ip")]
pub ipv4: Option<Ipv4Addr>,
#[serde(rename = "server_ipv6_net")]
pub ipv6_net: Ipv6Addr,
#[serde(rename = "server_number")]
pub id: ServerId,
#[serde(rename = "server_name")]
pub name: String,
pub product: String,
pub dc: String,
#[serde(rename = "traffic", deserialize_with = "crate::conversion::traffic")]
pub traffic_limit: Option<ByteSize>,
pub status: Status,
pub cancelled: bool,
pub paid_until: String,
#[serde(
rename = "ip",
default,
deserialize_with = "crate::conversion::deserialize_null_default"
)]
pub ips: Vec<String>,
#[serde(rename = "subnet", default)]
pub subnets: Vec<SubnetReference>,
#[serde(flatten)]
pub availability: Option<ServerFlags>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Cancelled {
#[serde(rename = "cancellation_date")]
pub date: Date,
#[serde(rename = "cancellation_reason")]
pub reason: Option<String>,
pub reserved: bool,
}
#[derive(Debug)]
pub struct Cancel {
pub date: Option<Date>,
pub reason: Option<String>,
pub reserved: bool,
}
#[derive(Serialize)]
pub(crate) struct InternalCancel {
#[serde(rename = "cancellation_date")]
pub date: String,
#[serde(rename = "cancellation_reason")]
pub reason: Option<String>,
pub reserved: bool,
}
impl From<Cancel> for InternalCancel {
fn from(value: Cancel) -> Self {
InternalCancel {
date: value
.date
.map(|date| date.to_string())
.unwrap_or("now".to_string()),
reason: value.reason,
reserved: value.reserved,
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Cancellable {
pub earliest_cancellation_date: Date,
pub reservation_possible: bool,
#[serde(rename = "cancellation_reason")]
pub cancellation_reasons: Vec<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Cancellation {
Cancelled(Cancelled),
Cancellable(Cancellable),
}
#[cfg(test)]
mod tests {
use crate::api::server::ServerId;
#[test]
fn server_id_conversion() {
assert_eq!(ServerId(10), ServerId::from(10));
assert_eq!(u32::from(ServerId(10)), 10);
assert_eq!(ServerId(10), 10);
}
}