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