diff options
Diffstat (limited to 'src/poem/anthology.rs')
-rw-r--r-- | src/poem/anthology.rs | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/src/poem/anthology.rs b/src/poem/anthology.rs index 086864c..0026b8d 100644 --- a/src/poem/anthology.rs +++ b/src/poem/anthology.rs @@ -15,7 +15,8 @@ static INDEX: [&str; 8] = [ /// Lookup the index of a built-in command /// -/// Looks up the index of a built-in command in [INDEX], accounting for aliases. +/// Looks up the index of a built-in command in [INDEX], accounting for +/// aliases. /// /// # Aliases /// * quit -> exit @@ -29,34 +30,67 @@ pub fn lookup(verb: &str) -> Option<usize> { INDEX.iter().position(|v| v.to_string() == verb) } +/// Dummy interface for STDIN +/// +/// A helper struct for dealing with STDIN in built-in commands. +/// Currently, there are no built-in commands that actually use this, +/// but it needs to exist for the `incant!()` macro to function +/// properly. See [Anthology] for more details. #[derive(Debug, PartialEq, Eq, Clone)] pub struct AnthologyStdin { + /// Bytes data: Vec<u8>, } impl AnthologyStdin { + /// Create a new instance of AnthologyStdin pub fn new() -> Self { AnthologyStdin { data: Vec::new() } } + /// Return a mutable version of self pub fn as_mut(&mut self) -> Option<&mut Self> { Some(self) } + /// Write bytes specified by data into STDIN pub fn write_all(&mut self, data: &[u8]) -> Result<(), io::Error> { self.data.append(&mut data.to_vec()); Ok(()) } } +/// Interface for built-in commands +/// +/// The implementation of [Anthology] is designed to mimic +/// [std::process::Command], in order to avoid code redundancy. The +/// internal structure of [Anthology] is fairly irrelevant to this +/// `impl`, with the exception of the `stdin`, and `output` fields. In +/// addition to the documentation below, it may also be helpful to read +/// through the `incant!()` macro, so see how processes are actually +/// forked. #[derive(Debug, Clone)] pub struct Anthology { + /// Name of the built-in command (see [lookup()] and/or [INDEX]) verb: String, + + /// Arguments to pass to the built-in command clause: Option<Vec<String>>, + + /// Indicates STDIN should be read in (but no built-ins use STDIN) uin: bool, + + /// Indicates STDOUT should be captured uout: bool, + + /// Indicates STDERR should be captured uerr: bool, + + /// Compatability with [std::process::Command] pub stdin: AnthologyStdin, + + /// Stores the built-in output (return code, STDOUT, STDERR), also + /// needed for compatability with [std::process::Command] output: Option<Output>, } @@ -110,11 +144,28 @@ impl Anthology { self.uerr = true; } + /// Set the process group + /// + /// This is only needed if a process is forked into the background. + /// Technically this is possible with the built-ins, but not really + /// useful, so this function simply does nothing. As a result, + /// built-ins that get forked into the background always return + /// immediately. pub fn process_group(&mut self, _id: usize) {} + + /// Get the process id + /// + /// This is only needed if a process is forked into the background. + /// Will always return `0` for built-in commands. Also see + /// [process_group()][Anthology::process_group]. pub fn id(&mut self) -> i32 { 0 } + /// Run a built-in command + /// + /// Runs a built-in command based on the `verb`, appropriately + /// passing arguments and [Environment] fields as necessary. pub fn spawn(&mut self, env: &mut Environment) -> Result<Self, io::Error> { // Incant the built-in and set the output self.output = Some(match self.verb.as_str() { @@ -132,6 +183,10 @@ impl Anthology { Ok(self.clone()) } + /// Get the output of a built-in + /// + /// Return the [Output] of a built-in command. This function needed + /// for compatibility with [std::process::Command]. pub fn wait_with_output(&self) -> Result<Output, io::Error> { match &self.output { Some(output) => Ok(output.clone()), |