summaryrefslogtreecommitdiffstats
path: root/src/recite.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/recite.rs')
-rw-r--r--src/recite.rs181
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