fly-sdk 0.1.3

Unofficial Fly.io SDK for Rust
Documentation
use crate::machines::{
    Checks, CpuKind, DnsConfig, FileConfig, GpuKind, GuestConfig, InitConfig, MetricsConfig,
    MountConfig, ProcessConfig, RestartPolicy, RestartPolicyEnum, ServiceConfig, StaticConfig,
    StopConfig,
};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum MachineState {
    Started,
    Stopped,
    Suspended,
    Destroyed,
}

impl std::fmt::Display for MachineState {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let state_str = match self {
            MachineState::Started => "started",
            MachineState::Stopped => "stopped",
            MachineState::Suspended => "suspended",
            MachineState::Destroyed => "destroyed",
        };
        write!(f, "{}", state_str)
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct MachineConfig {
    pub image: String,
    pub guest: Option<GuestConfig>,
    pub auto_destroy: Option<bool>,
    pub init: Option<InitConfig>,
    pub env: Option<HashMap<String, String>>,
    pub processes: Option<Vec<ProcessConfig>>,
    pub mounts: Option<Vec<MountConfig>>,
    pub restart: Option<RestartPolicy>,
    pub checks: Option<Checks>,
    pub dns: Option<DnsConfig>,
    pub files: Option<Vec<FileConfig>>,
    pub metadata: Option<HashMap<String, String>>,
    pub metrics: Option<MetricsConfig>,
    pub schedule: Option<String>,
    pub services: Option<Vec<ServiceConfig>>,
    pub standbys: Option<Vec<String>>,
    pub statics: Option<Vec<StaticConfig>>,
    pub stop_config: Option<StopConfig>,
}

impl Default for MachineConfig {
    fn default() -> Self {
        Self {
            image: "ubuntu:20.04".to_string(),
            env: None,
            processes: None,
            init: None,
            auto_destroy: Some(false),
            checks: None,
            dns: None,
            files: None,
            guest: None,
            metadata: None,
            metrics: None,
            mounts: None,
            restart: None,
            schedule: None,
            services: None,
            standbys: None,
            statics: None,
            stop_config: None,
        }
    }
}

impl MachineConfig {
    pub fn builder() -> MachineConfigBuilder {
        MachineConfigBuilder::new()
    }

    pub fn new(
        image: String,
        auto_destroy: Option<bool>,
        guest: Option<GuestConfig>,
        restart: Option<RestartPolicy>,
        env: Option<HashMap<String, String>>,
        processes: Option<Vec<ProcessConfig>>,
        mounts: Option<Vec<MountConfig>>,
        checks: Option<Checks>,
        dns: Option<DnsConfig>,
        files: Option<Vec<FileConfig>>,
        init: Option<InitConfig>,
        metrics: Option<MetricsConfig>,
        schedule: Option<String>,
        services: Option<Vec<ServiceConfig>>,
        standbys: Option<Vec<String>>,
        statics: Option<Vec<StaticConfig>>,
        stop_config: Option<StopConfig>,
    ) -> Self {
        Self {
            image,
            auto_destroy,
            guest,
            restart,
            env,
            processes,
            mounts,
            checks,
            dns,
            files,
            init,
            metadata: None,
            metrics,
            schedule,
            services,
            standbys,
            statics,
            stop_config,
        }
    }
}

pub struct MachineConfigBuilder {
    config: MachineConfig,
}

impl MachineConfigBuilder {
    pub fn new() -> Self {
        Self {
            config: MachineConfig {
                image: "ubuntu:22.04".to_string(),
                auto_destroy: Some(false),
                restart: Some(RestartPolicy::default()),
                guest: Some(GuestConfig::default()),
                ..Default::default()
            },
        }
    }

    pub fn image(mut self, image: &str) -> Self {
        self.config.image = image.to_string();
        self
    }

    pub fn auto_destroy(mut self, auto_destroy: bool) -> Self {
        self.config.auto_destroy = Some(auto_destroy);
        self
    }

    pub fn restart_policy(
        mut self,
        policy: RestartPolicyEnum,
        max_retries: Option<u32>,
        gpu_bid_price: Option<f64>,
    ) -> Self {
        self.config.restart = Some(RestartPolicy {
            policy: policy,
            max_retries,
            gpu_bid_price,
        });
        self
    }

    pub fn cpus(mut self, cpus: u64) -> Self {
        if let Some(guest) = &mut self.config.guest {
            guest.cpus = Some(cpus);
        }
        self
    }

    pub fn memory(mut self, memory_mb: u64) -> Self {
        if let Some(guest) = &mut self.config.guest {
            guest.memory_mb = Some(memory_mb);
        }
        self
    }

    pub fn cpu_kind(mut self, cpu_kind: CpuKind) -> Self {
        if let Some(guest) = &mut self.config.guest {
            guest.cpu_kind = Some(cpu_kind);
        }
        self
    }

    pub fn gpus(mut self, gpus: u64) -> Self {
        if let Some(guest) = &mut self.config.guest {
            guest.gpus = Some(gpus);
        }
        self
    }

    pub fn gpu_kind(mut self, gpu_kind: GpuKind) -> Self {
        if let Some(guest) = &mut self.config.guest {
            guest.gpu_kind = Some(gpu_kind);
        }
        self
    }

    pub fn checks(mut self, config: Checks) -> Self {
        self.config.checks = Some(config);
        self
    }

    pub fn dns(mut self, dns_config: DnsConfig) -> Self {
        self.config.dns = Some(dns_config);
        self
    }

    pub fn add_env(mut self, key: &str, value: &str) -> Self {
        if let Some(env) = &mut self.config.env {
            env.insert(key.to_string(), value.to_string());
        } else {
            let mut env = HashMap::new();
            env.insert(key.to_string(), value.to_string());
            self.config.env = Some(env);
        }
        self
    }

    pub fn add_file(mut self, file_config: FileConfig) -> Self {
        if let Some(files) = &mut self.config.files {
            files.push(file_config);
        } else {
            self.config.files = Some(vec![file_config]);
        }
        self
    }

    pub fn init(mut self, init_config: InitConfig) -> Self {
        self.config.init = Some(init_config);
        self
    }

    pub fn metrics(mut self, metrics_config: MetricsConfig) -> Self {
        self.config.metrics = Some(metrics_config);
        self
    }

    pub fn add_mount(mut self, mount_config: MountConfig) -> Self {
        if let Some(mounts) = &mut self.config.mounts {
            mounts.push(mount_config);
        } else {
            self.config.mounts = Some(vec![mount_config]);
        }
        self
    }

    pub fn add_process(mut self, process_config: ProcessConfig) -> Self {
        if let Some(processes) = &mut self.config.processes {
            processes.push(process_config);
        } else {
            self.config.processes = Some(vec![process_config]);
        }
        self
    }

    pub fn schedule(mut self, schedule: &str) -> Self {
        self.config.schedule = Some(schedule.to_string());
        self
    }

    pub fn add_service(mut self, service_config: ServiceConfig) -> Self {
        if let Some(services) = &mut self.config.services {
            services.push(service_config);
        } else {
            self.config.services = Some(vec![service_config]);
        }
        self
    }

    pub fn add_standby(mut self, standby: &str) -> Self {
        if let Some(standbys) = &mut self.config.standbys {
            standbys.push(standby.to_string());
        } else {
            self.config.standbys = Some(vec![standby.to_string()]);
        }
        self
    }

    pub fn add_static(mut self, static_config: StaticConfig) -> Self {
        if let Some(statics) = &mut self.config.statics {
            statics.push(static_config);
        } else {
            self.config.statics = Some(vec![static_config]);
        }
        self
    }

    pub fn stop_config(mut self, stop_config: StopConfig) -> Self {
        self.config.stop_config = Some(stop_config);
        self
    }

    pub fn build(self) -> MachineConfig {
        self.config
    }
}