use std::process::Command;
pub fn run(dsn: Option<&str>) -> Result<(), ScheduleError> {
let mut cmd = Command::new("cargo");
cmd.args(["run", "--", "--schedule"]);
if let Some(url) = dsn {
cmd.env("DATABASE_URL", url);
}
let status = cmd
.status()
.map_err(|source| ScheduleError::Spawn { source })?;
if !status.success() {
return Err(ScheduleError::Exited {
code: status.code(),
});
}
Ok(())
}
#[derive(Debug)]
pub enum ScheduleError {
Spawn { source: std::io::Error },
Exited { code: Option<i32> },
}
impl std::fmt::Display for ScheduleError {
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, "scheduler exited with status {c}"),
None => write!(f, "scheduler exited without a status"),
},
}
}
}
impl std::error::Error for ScheduleError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Spawn { source } => Some(source),
_ => None,
}
}
}