infrarust_server_manager 1.6.3

A Minecraft server manager that handles API monitoring and system commands
Documentation
use crate::ServerState;
use crate::api::{ApiProvider, ApiServerStatus};
use crate::error::ServerManagerError;
use async_trait::async_trait;
use reqwest::Client;
use serde::Deserialize;

#[derive(Clone, Debug)]
pub struct ApiClient {
    client: Client,
    base_url: String,
    auth_token: Option<String>,
}

impl ApiClient {
    pub fn new(base_url: &str) -> Self {
        let client = Client::new();
        ApiClient {
            client,
            base_url: base_url.to_string(),
            auth_token: None,
        }
    }

    pub fn with_auth(base_url: &str, auth_token: &str) -> Self {
        let client = Client::new();
        ApiClient {
            client,
            base_url: base_url.to_string(),
            auth_token: Some(auth_token.to_string()),
        }
    }
}

#[derive(Deserialize)]
struct ApiResponseStatus {
    id: String,
    name: String,
    status: String,
    is_running: bool,
    is_crashed: bool,
    error: Option<String>,
}

#[async_trait]
impl ApiProvider for ApiClient {
    async fn get_server_status(
        &self,
        server_id: &str,
    ) -> Result<ApiServerStatus, ServerManagerError> {
        let url = format!("{}/servers/{}/status", self.base_url, server_id);

        let mut request = self.client.get(&url);
        if let Some(token) = &self.auth_token {
            request = request.header("Authorization", format!("Bearer {}", token));
        }

        let response = request.send().await.map_err(|e| {
            ServerManagerError::ApiError(format!("Failed to get server status: {}", e))
        })?;

        if !response.status().is_success() {
            let status = response.status();
            let text = response
                .text()
                .await
                .unwrap_or_else(|_| "Unknown error".to_string());
            return Err(ServerManagerError::ApiError(format!(
                "API error ({}): {}",
                status, text
            )));
        }

        let status: ApiResponseStatus = response.json().await.map_err(|e| {
            ServerManagerError::ApiError(format!("Failed to parse response: {}", e))
        })?;

        Ok(ApiServerStatus {
            id: status.id,
            name: status.name,
            status: ServerState::from(status.status.as_str()),
            is_running: status.is_running,
            is_crashed: status.is_crashed,
            error: status.error,
        })
    }

    async fn start_server(&self, server_id: &str) -> Result<(), ServerManagerError> {
        let url = format!("{}/servers/{}/start", self.base_url, server_id);

        let mut request = self.client.post(&url);
        if let Some(token) = &self.auth_token {
            request = request.header("Authorization", format!("Bearer {}", token));
        }

        let response = request
            .send()
            .await
            .map_err(|e| ServerManagerError::ApiError(format!("Failed to start server: {}", e)))?;

        if !response.status().is_success() {
            let status = response.status();
            let text = response
                .text()
                .await
                .unwrap_or_else(|_| "Unknown error".to_string());
            return Err(ServerManagerError::ApiError(format!(
                "API error ({}): {}",
                status, text
            )));
        }

        Ok(())
    }

    async fn stop_server(&self, server_id: &str) -> Result<(), ServerManagerError> {
        let url = format!("{}/servers/{}/stop", self.base_url, server_id);

        let mut request = self.client.post(&url);
        if let Some(token) = &self.auth_token {
            request = request.header("Authorization", format!("Bearer {}", token));
        }

        let response = request
            .send()
            .await
            .map_err(|e| ServerManagerError::ApiError(format!("Failed to stop server: {}", e)))?;

        if !response.status().is_success() {
            let status = response.status();
            let text = response
                .text()
                .await
                .unwrap_or_else(|_| "Unknown error".to_string());
            return Err(ServerManagerError::ApiError(format!(
                "API error ({}): {}",
                status, text
            )));
        }

        Ok(())
    }
}