rush_sync_server/commands/start/
command.rs1use crate::commands::command::Command;
3use crate::core::prelude::*;
4use crate::server::handlers::web::create_web_server;
5use crate::server::types::{ServerContext, ServerStatus};
6use crate::server::utils::{port::is_port_available, validation::find_server};
7use std::future::Future;
8use std::pin::Pin;
9
10#[derive(Debug, Default)]
11pub struct StartCommand;
12
13impl StartCommand {
14 pub fn new() -> Self {
15 Self
16 }
17}
18
19impl Command for StartCommand {
20 fn name(&self) -> &'static str {
21 "start"
22 }
23 fn description(&self) -> &'static str {
24 "Start a web server"
25 }
26 fn matches(&self, command: &str) -> bool {
27 command.trim().to_lowercase().starts_with("start")
28 }
29
30 fn execute_sync(&self, args: &[&str]) -> Result<String> {
31 if args.is_empty() {
32 return Err(AppError::Validation(
33 "Server-ID/Name fehlt! Verwende 'start <ID>'".to_string(),
34 ));
35 }
36
37 let ctx = crate::server::shared::get_shared_context();
38 self.start_server_async(ctx, args[0])
39 }
40
41 fn execute_async<'a>(
42 &'a self,
43 args: &'a [&'a str],
44 ) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'a>> {
45 Box::pin(async move { self.execute_sync(args) })
46 }
47
48 fn supports_async(&self) -> bool {
49 true
50 }
51 fn priority(&self) -> u8 {
52 66
53 }
54}
55
56impl StartCommand {
57 fn start_server_async(&self, ctx: &ServerContext, identifier: &str) -> Result<String> {
58 let server_info = {
59 let servers = ctx.servers.read().unwrap();
60 find_server(&servers, identifier)?.clone()
61 };
62
63 if server_info.status == ServerStatus::Running {
64 return Ok(format!("Server '{}' läuft bereits!", server_info.name));
65 }
66
67 if !is_port_available(server_info.port) {
68 return Ok(format!("Port {} bereits belegt!", server_info.port));
69 }
70
71 match self.spawn_server(ctx, server_info.clone()) {
72 Ok(handle) => {
73 {
74 let mut handles = ctx.handles.write().unwrap();
75 handles.insert(server_info.id.clone(), handle);
76 }
77 self.update_server_status(ctx, &server_info.id, ServerStatus::Running);
78 Ok(format!(
79 "Server '{}' erfolgreich gestartet auf http://127.0.0.1:{}",
80 server_info.name, server_info.port
81 ))
82 }
83 Err(e) => {
84 self.update_server_status(ctx, &server_info.id, ServerStatus::Failed);
85 Err(AppError::Validation(format!(
86 "Server-Start fehlgeschlagen: {}",
87 e
88 )))
89 }
90 }
91 }
92
93 fn spawn_server(
94 &self,
95 ctx: &ServerContext,
96 server_info: crate::server::types::ServerInfo,
97 ) -> std::result::Result<actix_web::dev::ServerHandle, String> {
98 create_web_server(ctx, server_info)
99 }
100
101 fn update_server_status(&self, ctx: &ServerContext, server_id: &str, status: ServerStatus) {
102 if let Ok(mut servers) = ctx.servers.write() {
103 if let Some(server) = servers.get_mut(server_id) {
104 server.status = status;
105 }
106 }
107 }
108}