folk 0.1.4

Reference binary for Folk PHP application server
//! Folk reference binary.
//!
//! Provides a CLI entry point for the Folk application server.

use std::sync::Arc;

use clap::{Parser, Subcommand};
use folk_core::config::{FolkConfig, RuntimeKind};
use folk_core::runtime::Runtime;

#[derive(Parser)]
#[command(name = "folk", version = folk_api::FOLK_API_VERSION)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    Serve {
        #[arg(short, long, default_value = "folk.toml")]
        config: String,
    },
    Version,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let cli = Cli::parse();
    match cli.command {
        Commands::Serve { config } => {
            let cfg = FolkConfig::load_from(&config)?;
            let runtime: Arc<dyn Runtime> = match cfg.server.runtime {
                RuntimeKind::Pipe => Arc::new(folk_runtime_pipe::PipeRuntime::new(
                    folk_runtime_pipe::PipeConfig {
                        php: cfg.workers.php.clone(),
                        script: cfg.workers.script.clone(),
                    },
                )),
                RuntimeKind::Fork => {
                    folk_runtime_fork::ForkRuntime::new(folk_runtime_fork::ForkConfig {
                        php: cfg.workers.php.clone(),
                        script: cfg.workers.script.clone(),
                        boot_timeout: cfg.workers.boot_timeout,
                    })
                    .await?
                },
                #[cfg(feature = "embed")]
                RuntimeKind::Embed => {
                    let mut rt =
                        folk_runtime_embed::EmbedRuntime::new(folk_runtime_embed::EmbedConfig {
                            script: Some(cfg.workers.script.clone()),
                            warmup_files: vec!["vendor/autoload.php".to_string()],
                        });
                    rt.warmup().await?;
                    Arc::new(rt)
                },
                #[cfg(not(feature = "embed"))]
                RuntimeKind::Embed => {
                    anyhow::bail!("embed runtime not available: rebuild with `--features embed`");
                },
            };
            let server = folk_core::server::FolkServer::new(cfg, runtime);
            server.run().await
        },
        Commands::Version => {
            println!("folk {}", folk_api::FOLK_API_VERSION);
            Ok(())
        },
    }
}