innisfree 0.4.3

Exposes local services on public IPv4 address, via cloud server.
Documentation
//! [`Provider`] implementation for DigitalOcean.
//!
//! Holds the authenticated [`DoClient`] (constructed once at startup)
//! and hands it to [`Droplet::new`] each time a server is requested.

use anyhow::Result;
use async_trait::async_trait;

use crate::server::digitalocean::client::DoClient;
use crate::server::digitalocean::server::{Droplet, DropletDefaults};
use crate::server::{InnisfreeServer, Provider, ServerSpec};

/// DigitalOcean factory. Construct once with [`DoClient::from_env`] and
/// a [`DropletDefaults`] (typically wired from the CLI flags), then
/// pass to [`crate::manager::TunnelManager::new`].
pub struct DigitalOceanProvider {
    client: DoClient,
    defaults: DropletDefaults,
}

impl DigitalOceanProvider {
    /// Wrap a configured [`DoClient`] as a [`Provider`]. Use
    /// [`DropletDefaults::default`] for the compiled-in region/size/image
    /// constants, or build one explicitly to honour CLI overrides.
    pub fn new(client: DoClient, defaults: DropletDefaults) -> Self {
        Self { client, defaults }
    }
}

#[async_trait]
impl Provider for DigitalOceanProvider {
    async fn create(&self, spec: &ServerSpec) -> Result<Box<dyn InnisfreeServer>> {
        let droplet = Droplet::new(self.client.clone(), spec, &self.defaults).await?;
        Ok(Box::new(droplet))
    }
}