diff options
Diffstat (limited to 'src/recite.rs')
-rw-r--r-- | src/recite.rs | 181 |
1 files changed, 70 insertions, 111 deletions
diff --git a/src/recite.rs b/src/recite.rs index 4e1dc1f..bfcd6b1 100644 --- a/src/recite.rs +++ b/src/recite.rs @@ -1,5 +1,10 @@ +pub mod erro; pub mod path; +mod ps; +use crate::ctask; +use crate::task; use core::fmt; +use erro::Mishap; use path::prefresh; use std::io::{self, Write}; use std::path::Path; @@ -44,6 +49,56 @@ impl fmt::Display for Meter { } } +impl Meter { + fn incant_none(verse: &Verse, out: &mut String) -> Result<i32, Mishap> { + let child = task!(verse, out); + + let output = child + .wait_with_output() + .map_err(|_| Mishap::Terminated(verse.stanza.to_string()))?; + + if !output.status.success() { + return Err(Mishap::Else(verse.stanza.to_string())); + } + + Ok(output.status.code().unwrap_or(0)) + } + + fn incant_couplet(verse: &Verse, out: &mut String) -> Result<i32, Mishap> { + let child = ctask!(verse, out); + + let output = child + .wait_with_output() + .map_err(|_| Mishap::Terminated(verse.stanza.to_string()))?; + + if !output.status.success() { + return Err(Mishap::Else(verse.stanza.to_string())); + } + + out.push_str( + String::from_utf8_lossy(&output.stdout) + .into_owned() + .as_str(), + ); + + Ok(output.status.code().unwrap_or(0)) + } + + fn incant_quiet(verse: &Verse, out: &mut String) -> Result<i32, Mishap> { + let child = task!(verse, out); + println!("[&] {}", child.id()); + Ok(0) + } + + fn incant_and(verse: &Verse, out: &mut String) -> Result<i32, Mishap> { + Meter::incant_none(verse, out) + } + + fn incant_string(verse: &Verse, out: &mut String) -> Result<i32, Mishap> { + Meter::incant_none(verse, out) + } +} + /// Holds a program to be called /// /// This is simply the first word in a full command [String], dilineated via @@ -259,7 +314,7 @@ impl Poem { /// None => {} /// } /// ``` - pub fn recite(&self, path: &Vec<&Path>, bins: &mut Vec<String>) -> bool { + pub fn recite(&self, path: &Vec<&Path>, bins: &mut Vec<String>) -> Result<(), Mishap> { // Variable for storing the output of a piped verse let mut out: String = String::new(); @@ -300,121 +355,25 @@ impl Poem { } } - // If the verse is a couplet, it means it needs the output of the - // previous verse on `STDIN` - if verse.couplet { - match verse.meter { - Meter::Couplet => { - let mut child = Command::new(verse.verb()) - .args(verse.clause()) - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .expect("dwvsh: error 0"); - - let stdin = child.stdin.as_mut().expect("dwvsh: error 6"); - stdin.write_all(&out.as_bytes()).expect("dwvsh: error 7"); - out.clear(); - - let output = child.wait_with_output().unwrap(); - out = String::from_utf8_lossy(&output.stdout).to_string(); + // Incant the verse, based on its meter + match verse.meter { + Meter::None => Meter::incant_none(verse, &mut out)?, + Meter::Couplet => Meter::incant_couplet(verse, &mut out)?, + Meter::Quiet => Meter::incant_quiet(verse, &mut out)?, + Meter::And => Meter::incant_and(verse, &mut out)?, + Meter::String => match Meter::incant_string(verse, &mut out) { + Ok(_) => 0, + Err(e) => { + eprintln!("dwvsh: {}", e); + 1 } - Meter::Quiet => { - let mut child = Command::new(verse.verb()) - .args(verse.clause()) - .stdin(Stdio::piped()) - .spawn() - .expect("dwvsh: error 1"); - - let stdin = child.stdin.as_mut().expect("dwvsh: error 8"); - stdin.write_all(&out.as_bytes()).expect("dwvsh: error 9"); - out.clear(); - - print!("[f] {}", child.id()); - std::thread::spawn(move || { - child.wait().unwrap(); - println!("[f] +done {}", child.id()); - io::stdout().flush().unwrap(); - }); - } - Meter::String => { - let mut child = Command::new(verse.verb()) - .args(verse.clause()) - .spawn() - .expect("dwvsh: error 5"); - - let stdin = child.stdin.as_mut().expect("dwvsh: error 8"); - stdin.write_all(&out.as_bytes()).expect("dwvsh: error 9"); - out.clear(); - - child.wait().unwrap(); - } - Meter::And | Meter::None => { - let mut child = Command::new(verse.verb()) - .args(verse.clause()) - .stdin(Stdio::piped()) - .spawn() - .expect("dwvsh: error 2"); - - let stdin = child.stdin.as_mut().expect("dwvsh: error 10"); - stdin.write_all(&out.as_bytes()).expect("dwvsh: error 11"); - out.clear(); - - if !child.wait().unwrap().success() { - break; - } - } - }; - } else { - match verse.meter { - Meter::Couplet => { - let child = Command::new(verse.verb()) - .args(verse.clause()) - .stdout(Stdio::piped()) - .spawn() - .expect("dwvsh: error 3"); - - let output = child.wait_with_output().unwrap(); - out = String::from_utf8_lossy(&output.stdout).to_string(); - } - Meter::Quiet => { - let mut child = Command::new(verse.verb()) - .args(verse.clause()) - .spawn() - .expect("dwvsh: error 4"); - - println!("[f] {}", child.id()); - std::thread::spawn(move || { - child.wait().unwrap(); - print!("[f] +done {}\n", child.id()); - io::stdout().flush().unwrap(); - }); - } - Meter::String => { - let mut child = Command::new(verse.verb()) - .args(verse.clause()) - .spawn() - .expect("dwvsh: error 5"); - - child.wait().unwrap(); - } - Meter::And | Meter::None => { - let mut child = Command::new(verse.verb()) - .args(verse.clause()) - .spawn() - .expect("dwvsh: error 5"); - - if !child.wait().unwrap().success() { - break; - } - } - }; - } + }, + }; } // If we've successfully exited the loop, then all verse's were // properly recited - true + Ok(()) } /// Parse a [Poem] from a raw [String] input |