use std::process::Command;
use std::process::Stdio;
use spell_checker::SpellChecker;
use error::{Result, Error};
#[derive(Debug)]
pub struct SpellLauncher {
lang: Option<String>,
command: Option<String>,
mode: Mode,
timeout: u64,
}
#[derive(Debug)]
enum Mode {
Ispell,
Aspell,
Hunspell,
}
impl SpellLauncher {
pub fn new() -> SpellLauncher {
SpellLauncher {
lang: None,
command: None,
mode: Mode::Ispell,
timeout: 1000,
}
}
pub fn aspell(&mut self) -> &mut SpellLauncher {
self.mode = Mode::Aspell;
self
}
pub fn hunspell(&mut self) -> &mut SpellLauncher {
self.mode = Mode::Hunspell;
self
}
pub fn ispell(&mut self) -> &mut SpellLauncher {
self.mode = Mode::Ispell;
self
}
pub fn timeout(&mut self, timeout: u64) -> &mut SpellLauncher {
self.timeout = timeout;
self
}
pub fn command<S: Into<String>>(&mut self, command: S) -> &mut SpellLauncher {
self.command = Some(command.into());
self
}
pub fn dictionary<S: Into<String>>(&mut self, lang: S) -> &mut SpellLauncher {
self.lang = Some(lang.into());
self
}
pub fn launch(&self) -> Result<SpellChecker> {
let command_name: &str = if let Some(ref command) = self.command {
command
} else {
match self.mode {
Mode::Ispell => "ispell",
Mode::Aspell => "aspell",
Mode::Hunspell => "hunspell",
}
};
let mut command = Command::new(command_name);
command.arg("-a")
.stdin(Stdio::piped())
.stdout(Stdio::piped());
if let Some(ref lang) = self.lang {
command.arg("-d")
.arg(lang);
}
if self.command.is_none() { match self.mode {
Mode::Hunspell => command.args(&["-i", "utf-8"]),
Mode::Aspell => command.arg("--encoding=utf-8"),
Mode::Ispell => command.arg("-Tutf8"),
};
}
let res = command.spawn();
match res {
Ok(child) => SpellChecker::new(child, self.timeout),
Err(err) => Err(Error::process(format!("could not successfully spawn process '{}': {}", command_name, err)))
}
}
}