infrarust_server_manager 1.6.3

A Minecraft server manager that handles API monitoring and system commands
Documentation
use async_trait::async_trait;
use std::collections::HashMap;
use std::sync::{Arc, RwLock};

use crate::ServerState;
use crate::api::{ApiProvider, ApiServerStatus};
use crate::error::ServerManagerError;

#[derive(Clone, Debug)]
pub struct MockApiProvider {
    server_states: Arc<RwLock<HashMap<String, ApiServerStatus>>>,
}

impl Default for MockApiProvider {
    fn default() -> Self {
        Self::new()
    }
}

impl MockApiProvider {
    pub fn new() -> Self {
        Self {
            server_states: Arc::new(RwLock::new(HashMap::new())),
        }
    }

    pub fn with_server(self, server_id: &str, status: ApiServerStatus) -> Self {
        self.server_states
            .write()
            .unwrap()
            .insert(server_id.to_string(), status);
        self
    }

    pub fn set_server_crashed(&self, server_id: &str) {
        let mut states = self.server_states.write().unwrap();
        if let Some(status) = states.get_mut(server_id) {
            status.is_running = false;
            status.is_crashed = true;
            status.status = ServerState::Crashed;
            status.error = Some("Server has crashed".to_string());
        }
    }

    pub fn set_server_running(&self, server_id: &str) {
        let mut states = self.server_states.write().unwrap();
        if let Some(status) = states.get_mut(server_id) {
            status.is_running = true;
            status.is_crashed = false;
            status.status = ServerState::Running;
            status.error = None;
        }
    }

    pub fn set_server_stopped(&self, server_id: &str) {
        let mut states = self.server_states.write().unwrap();
        if let Some(status) = states.get_mut(server_id) {
            status.is_running = false;
            status.is_crashed = false;
            status.status = ServerState::Stopped;
            status.error = None;
        }
    }
}

#[async_trait]
impl ApiProvider for MockApiProvider {
    async fn get_server_status(
        &self,
        server_id: &str,
    ) -> Result<ApiServerStatus, ServerManagerError> {
        let states = self.server_states.read().unwrap();
        match states.get(server_id) {
            Some(status) => Ok(status.clone()),
            None => Err(ServerManagerError::ApiError(format!(
                "Server {} not found",
                server_id
            ))),
        }
    }

    async fn start_server(&self, server_id: &str) -> Result<(), ServerManagerError> {
        let states = self.server_states.read().unwrap();
        if !states.contains_key(server_id) {
            return Err(ServerManagerError::ApiError(format!(
                "Server {} not found",
                server_id
            )));
        }
        drop(states);

        self.set_server_running(server_id);
        Ok(())
    }

    async fn stop_server(&self, server_id: &str) -> Result<(), ServerManagerError> {
        let states = self.server_states.read().unwrap();
        if !states.contains_key(server_id) {
            return Err(ServerManagerError::ApiError(format!(
                "Server {} not found",
                server_id
            )));
        }
        drop(states);

        self.set_server_stopped(server_id);
        Ok(())
    }
}