use async_trait::async_trait;
use infrarust_server_manager::{
LocalProvider, ProcessProvider, ServerManager, ServerManagerError, local::LocalServerConfig,
};
use tokio::sync::mpsc;
use tokio::time::{Duration, sleep};
#[derive(Clone, Debug)]
struct CustomProcessProvider {
local_provider: LocalProvider,
}
impl CustomProcessProvider {
fn new(provider: LocalProvider) -> Self {
Self {
local_provider: provider,
}
}
async fn register_server(&self, server_id: &str, config: LocalServerConfig) {
self.local_provider.register_server(server_id, config).await;
}
}
#[async_trait]
impl ProcessProvider for CustomProcessProvider {
async fn write_stdin(&self, server_id: &str, input: &str) -> Result<(), ServerManagerError> {
println!("CustomProvider: writing to stdin: {}", input);
self.local_provider.write_stdin(server_id, input).await
}
fn get_stdout_stream(
&self,
server_id: &str,
) -> Result<mpsc::Receiver<String>, ServerManagerError> {
println!("CustomProvider: getting stdout stream");
self.local_provider.get_stdout_stream(server_id)
}
fn is_process_running(&self, server_id: &str) -> Result<bool, ServerManagerError> {
self.local_provider.is_process_running(server_id)
}
async fn stop_process(&self, server_id: &str) -> Result<(), ServerManagerError> {
println!("CustomProvider: stopping process");
self.local_provider.stop_process(server_id).await
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
{
println!("=== Example 1: Using LocalProvider as both API and Process provider ===");
let local_provider = LocalProvider::new();
let server_config = LocalServerConfig {
#[cfg(target_os = "windows")]
executable: "cmd".to_string(),
#[cfg(target_os = "windows")]
args: vec!["/K", "echo Server starting..."]
.iter()
.map(|s| s.to_string())
.collect(),
#[cfg(not(target_os = "windows"))]
executable: "bash".to_string(),
#[cfg(not(target_os = "windows"))]
args: [
"-c",
"echo 'Server starting...' && while read line; do echo \"Server: $line\"; done",
]
.iter()
.map(|s| s.to_string())
.collect(),
working_dir: None,
startup_string: Some("Server starting...".to_string()),
};
local_provider
.register_server("echo-server", server_config)
.await;
let server_manager =
ServerManager::new(local_provider.clone()).with_process_provider(local_provider);
server_manager.start_server("echo-server").await?;
println!("Server started");
let mut stdout_stream = server_manager.get_stdout_stream("echo-server")?;
let _output_task = tokio::spawn(async move {
while let Some(line) = stdout_stream.recv().await {
println!("Output: {}", line);
}
});
sleep(Duration::from_secs(1)).await;
server_manager
.write_stdin("echo-server", "Hello from direct provider!")
.await?;
sleep(Duration::from_secs(1)).await;
server_manager.stop_server("echo-server").await?;
sleep(Duration::from_secs(2)).await;
}
{
println!("\n=== Example 2: Using a custom process provider ===");
let server_config = LocalServerConfig {
#[cfg(target_os = "windows")]
executable: "cmd".to_string(),
#[cfg(target_os = "windows")]
args: vec!["/K", "echo Custom server starting..."]
.iter()
.map(|s| s.to_string())
.collect(),
#[cfg(not(target_os = "windows"))]
executable: "bash".to_string(),
#[cfg(not(target_os = "windows"))]
args: ["-c",
"echo 'Custom server starting...' && while read line; do echo \"Custom: $line\"; done"]
.iter()
.map(|s| s.to_string())
.collect(),
working_dir: None,
startup_string: Some("Custom server starting...".to_string()),
};
let local_provider = LocalProvider::new();
let custom_provider = CustomProcessProvider::new(local_provider.clone());
custom_provider
.register_server("custom-server", server_config)
.await;
let server_manager =
ServerManager::new(local_provider).with_process_provider(custom_provider.clone());
println!("Starting server: custom-server");
server_manager.start_server("custom-server").await?;
println!("Custom server started");
let mut stdout_stream = server_manager.get_stdout_stream("custom-server")?;
let _output_task = tokio::spawn(async move {
while let Some(line) = stdout_stream.recv().await {
println!("Custom output: {}", line);
}
});
sleep(Duration::from_secs(1)).await;
server_manager
.write_stdin("custom-server", "Hello from custom provider!")
.await?;
sleep(Duration::from_secs(1)).await;
server_manager.stop_server("custom-server").await?;
sleep(Duration::from_secs(2)).await;
println!("Example completed successfully!");
Ok(())
}
}