use std::process::Command;
pub fn run(bind: Option<&str>, port: Option<u16>) -> Result<(), ServeError> {
let mut cmd = Command::new("cargo");
cmd.arg("run");
if let Some(p) = port {
cmd.env("ARCATURE_BACKEND_PORT", p.to_string());
}
if let Some(addr) = bind {
cmd.env("ARCATURE_BACKEND_BIND", addr);
}
let status = cmd
.status()
.map_err(|source| ServeError::Spawn { source })?;
if !status.success() {
return Err(ServeError::Exited {
code: status.code(),
});
}
Ok(())
}
#[derive(Debug)]
pub enum ServeError {
Spawn { source: std::io::Error },
Exited { code: Option<i32> },
}
impl std::fmt::Display for ServeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Spawn { source } => write!(f, "failed to spawn cargo: {source}"),
Self::Exited { code } => match code {
Some(c) => write!(f, "cargo run exited with status {c}"),
None => write!(f, "cargo run exited without a status"),
},
}
}
}
impl std::error::Error for ServeError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Spawn { source } => Some(source),
_ => None,
}
}
}