diff options
Diffstat (limited to 'src/poem/anthology.rs')
-rw-r--r-- | src/poem/anthology.rs | 142 |
1 files changed, 129 insertions, 13 deletions
diff --git a/src/poem/anthology.rs b/src/poem/anthology.rs index 8ff70f9..a35eafb 100644 --- a/src/poem/anthology.rs +++ b/src/poem/anthology.rs @@ -5,7 +5,8 @@ mod export; mod source; mod which; use crate::compose::Environment; -use crate::poem::Verse; +use std::io; +use std::process::{Output, Stdio}; /// A static list of all the built-in commands static INDEX: [&str; 8] = [ @@ -44,17 +45,132 @@ pub fn lookup(verb: &str) -> Option<usize> { /// ... /// } /// ``` -pub fn incant(verse: &Verse, out: &mut Vec<u8>, index: usize, env: &mut Environment) -> i32 { - let verb = INDEX[index]; - match verb { - "alias" => alias::incant(verse, out, &mut env.aliases), - "cd" => cd::incant(verse), - "exit" => exit::incant(), - "export" => export::incant(verse), - "source" => source::incant(verse, out, env), - "unalias" => alias::unincant(verse, &mut env.aliases), - "unset" => export::unincant(verse), - "which" => which::incant(verse, out, env), - _ => unreachable!(), +// pub fn incant(verse: &Verse, out: &mut Vec<u8>, index: usize, env: &mut Environment) -> i32 { +// // let verb = INDEX[index]; +// // match verb { +// // "alias" => alias::incant(verse, out, &mut env.aliases), +// // "cd" => cd::incant(verse), +// // "exit" => exit::incant(), +// // "export" => export::incant(verse), +// // "source" => source::incant(verse, out, env), +// // "unalias" => alias::unincant(verse, &mut env.aliases), +// // "unset" => export::unincant(verse), +// // "which" => which::incant(verse, out, env), +// // _ => unreachable!(), +// // } +// 0 +// } + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct AnthologyStdin { + data: Vec<u8>, +} + +impl AnthologyStdin { + pub fn new() -> Self { + AnthologyStdin { data: Vec::new() } + } + + pub fn as_mut(&mut self) -> Option<&mut Self> { + Some(self) + } + + pub fn write_all(&mut self, data: &[u8]) -> Result<(), io::Error> { + self.data.append(&mut data.to_vec()); + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct Anthology { + verb: String, + clause: Option<Vec<String>>, + uin: bool, + uout: bool, + uerr: bool, + pub stdin: AnthologyStdin, + output: Option<Output>, +} + +impl Anthology { + /// Create a new instance of a built-in command + /// + /// Sets up a built-in command with default values. + /// + /// # Examples + /// ``` + /// let mut command = Anthology::new("alias"); + /// ``` + pub fn new(verb: String) -> Self { + Anthology { + verb, + clause: None, + uin: false, + uout: false, + uerr: false, + stdin: AnthologyStdin::new(), + output: None, + } + } + + /// Setup arguments to the built-in command + /// + /// Sets the 'clause' field of the [Anthology] struct, which are arguments + /// to be passed to the built-in command. + pub fn args(&mut self, clause: Vec<String>) { + self.clause = match clause.is_empty() { + true => None, + false => Some(clause.clone()), + }; + } + + /// Read to STDIN + /// + /// None of the built-in commands will currently read from STDIN for any + /// reason, so this is just a dummy function. + pub fn stdin(&mut self, _stdin: Stdio) { + self.uin = true; + } + + /// Capture STDOUT + pub fn stdout(&mut self, _stdout: Stdio) { + self.uout = true; + } + + /// Capture STDERR + pub fn stderr(&mut self, _stderr: Stdio) { + self.uerr = true; + } + + pub fn process_group(&mut self, _id: usize) {} + pub fn id(&mut self) -> i32 { + 0 + } + + pub fn spawn(&mut self, env: &mut Environment) -> Result<Self, io::Error> { + let index = lookup(self.verb.as_str()).unwrap(); + let verb = INDEX[index]; + + // Incant the built-in and set the output + self.output = Some(match verb { + "alias" => alias::incant(&self.clause, self.uout, &mut env.aliases), + "cd" => cd::incant(&self.clause, self.uerr), + "exit" => exit::incant(), + "export" => export::incant(&self.clause, self.uout), + "source" => source::incant(&self.clause, self.uout, self.uerr, env), + "unalias" => alias::unincant(&self.clause, self.uerr, &mut env.aliases), + "unset" => export::unincant(&self.clause, self.uerr), + "which" => which::incant(&self.clause, self.uout, self.uerr, env), + _ => unreachable!(), + }); + + Ok(self.clone()) + } + + pub fn wait_with_output(&self) -> Result<Output, io::Error> { + match &self.output { + Some(output) => Ok(output.clone()), + None => Err(io::Error::new(io::ErrorKind::Other, "not spawned")), + } } } |