use crate::config::{update_config, update_episode, Config}; use crate::initialization::init_config; use crate::result::{AppError, AppResult}; use crate::{generate_completion, Opt, RunMode}; use std::process::Command; pub fn run(opts: Opt) -> AppResult<()> { let mode = opts.mode.unwrap_or_else(|| RunMode::Play); match mode { RunMode::Init => init_config(), RunMode::Play => play(), RunMode::Prev => update_episode(prev_episode), RunMode::Next => update_episode(next_episode), RunMode::Update => update_config(), RunMode::Reset => update_episode(|_| Ok(0)), RunMode::Completion { shell } => generate_completion(shell), } } pub fn prev_episode(current: usize) -> AppResult { if let Some(episode) = current.checked_sub(1) { Ok(episode) } else { Err(AppError::RuntimeError(String::from( "Episode can't be less than zero.", ))) } } pub fn next_episode(current: usize) -> AppResult { if let Some(episode) = current.checked_add(1) { Ok(episode) } else { Err(AppError::RuntimeError(String::from( "Reached usize limit. Sorry.", ))) } } fn add_leading_zero(n: usize) -> String { if n < 10 { format!("0{}", n) } else { format!("{}", n) } } fn prepare_command(conf: Config) -> AppResult { let index = conf.current_episode_count; Ok(conf .command .replace("{}", conf.get_current_episode()?.as_str()) .replace("{n}", format!("{}", index).as_str()) .replace("{n+}", format!("{}", index + 1).as_str()) .replace("{zn}", add_leading_zero(index).as_str()) .replace("{zn+}", add_leading_zero(index + 1).as_str())) } pub fn play() -> AppResult<()> { let mut conf = Config::read()?; let mut episode = conf.get_current_episode()?; while !episode.is_empty() { let mut child = Command::new("sh") .arg("-c") .arg(prepare_command(conf.clone())?) .spawn()?; child.wait()?; update_episode(next_episode)?; conf = Config::read()?; episode = conf.get_current_episode()?; } Ok(()) }