use clap::{CommandFactory, Parser};
use clap_complete::{generate, Shell};
use crossterm;
use snakepipe::cli::{AvailableShells, Cli, CliOptions, Commands};
use snakepipe::gamestate::run as gamestate_run;
use snakepipe::input::InitOptions;
use snakepipe::net::common::StreamType;
use snakepipe::net::play::block_on_play;
use snakepipe::net::watch::block_on_watch;
use snakepipe::pipeline::generate_command as pipeline_generate_command;
use snakepipe::render::run as render_run;
use snakepipe::render_browser::common::port_is_available;
use snakepipe::render_browser::run as render_browser_run;
use snakepipe::stream_sse::run as stream_sse_run;
use snakepipe::throttle::run as throttle_run;
use snakepipe::utils::resolve_path;
fn generate_completion(shell: Shell) {
generate(
shell,
&mut Cli::command(),
"snakepipe",
&mut std::io::stdout(),
)
}
fn main() {
let cli = Cli::parse();
match &cli.command {
Commands::Gamestate {
frame_duration,
width,
height,
snake_length,
fit_terminal,
} => {
let cli_options = CliOptions {
frame_duration: frame_duration,
width: width,
height: height,
snake_length: snake_length,
fit_terminal: fit_terminal,
};
let game_options: InitOptions = cli_options.into();
let _ = crossterm::terminal::enable_raw_mode();
let _ = gamestate_run(game_options); let _ = crossterm::terminal::disable_raw_mode();
std::process::exit(130); }
Commands::Render => {
render_run();
}
Commands::Throttle {
frame_duration,
loop_infinite,
} => throttle_run(*frame_duration, *loop_infinite),
Commands::RenderBrowser { port } => {
if port_is_available(*port) {
return render_browser_run(*port);
}
eprintln!("Error: port {} already in use", port);
std::process::exit(exitcode::UNAVAILABLE);
}
Commands::StreamSse { address } => stream_sse_run(address.to_string()),
#[cfg(unix)]
Commands::SocketPlay { path } => match resolve_path(std::path::PathBuf::from(&path)) {
Ok(path) => {
match std::fs::remove_file(&path) {
Ok(_) => {}
Err(err) => {
if err.kind() != std::io::ErrorKind::NotFound {
eprintln!("Failed to remove {:?}", &path);
std::process::exit(exitcode::OSFILE);
}
}
}
let _ = block_on_play(StreamType::Socket(path));
}
Err(_) => {
eprintln!("{} not found.", path);
std::process::exit(exitcode::OSFILE);
}
},
#[cfg(unix)]
Commands::SocketWatch { path } => match resolve_path(std::path::PathBuf::from(&path)) {
Ok(path) => {
if let Err(_) = block_on_watch(StreamType::Socket(path)) {
std::process::exit(exitcode::IOERR);
}
}
Err(_) => {
eprintln!("{} not found.", path);
std::process::exit(exitcode::OSFILE);
}
},
Commands::TcpPlay { port, host } => {
let _ = block_on_play(StreamType::Tcp(format!("{}:{}", host, port).to_string()));
}
Commands::TcpWatch { port, host } => {
let _ = block_on_watch(StreamType::Tcp(format!("{}:{}", host, port).to_string()));
}
Commands::Pipeline(cmd) => pipeline_generate_command(cmd.sub, cmd.list, ""),
Commands::GenerateCompletions(flags) => match flags.shell {
AvailableShells::Bash => generate_completion(Shell::Bash),
AvailableShells::Fish => generate_completion(Shell::Fish),
AvailableShells::Zsh => generate_completion(Shell::Zsh),
},
}
}