Skip to content

Commit

Permalink
Add builder style configuration of user input, output and error
Browse files Browse the repository at this point in the history
  • Loading branch information
bakaq committed Feb 5, 2025
1 parent 975fbe4 commit ee8b7c4
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 34 deletions.
55 changes: 35 additions & 20 deletions src/machine/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,9 @@ impl InputStreamConfig {

/// Describes how the streams of a [`Machine`](crate::Machine) will be handled.
pub struct StreamConfig {
/// The configuration for the stdin of the [`Machine`](crate::Machine).
pub stdin: InputStreamConfig,
/// The configuration for the stdout of the [`Machine`](crate::Machine).
pub stdout: OutputStreamConfig,
/// The configuration for the stderr of the [`Machine`](crate::Machine).
pub stderr: OutputStreamConfig,
user_input: InputStreamConfig,
user_output: OutputStreamConfig,
user_error: OutputStreamConfig,
}

impl Default for StreamConfig {
Expand All @@ -150,43 +147,61 @@ impl StreamConfig {
/// Binds the input, output and error streams to stdin, stdout and stderr.
pub fn stdio() -> Self {
StreamConfig {
stdin: InputStreamConfig::stdin(),
stdout: OutputStreamConfig::stdout(),
stderr: OutputStreamConfig::stderr(),
user_input: InputStreamConfig::stdin(),
user_output: OutputStreamConfig::stdout(),
user_error: OutputStreamConfig::stderr(),
}
}

/// Binds the output and error streams to memory buffers and has an empty input.
pub fn in_memory() -> Self {
StreamConfig {
stdin: InputStreamConfig::string(""),
stdout: OutputStreamConfig::memory(),
stderr: OutputStreamConfig::memory(),
user_input: InputStreamConfig::string(""),
user_output: OutputStreamConfig::memory(),
user_error: OutputStreamConfig::memory(),
}
}

/// Calls the given callbacks when the respective streams are written to.
///
/// This also returns a handler to the stdin do the [`Machine`](crate::Machine).
pub fn with_callbacks(stdout: Option<Callback>, stderr: Option<Callback>) -> (UserInput, Self) {
/// This also returns a handler to the stdin of the [`Machine`](crate::Machine).
pub fn from_callbacks(stdout: Option<Callback>, stderr: Option<Callback>) -> (UserInput, Self) {
let (user_input, channel_stream) = InputStreamConfig::channel();
(
user_input,
StreamConfig {
stdin: channel_stream,
stdout: stdout
user_input: channel_stream,
user_output: stdout
.map_or_else(OutputStreamConfig::memory, OutputStreamConfig::callback),
stderr: stderr
user_error: stderr
.map_or_else(OutputStreamConfig::memory, OutputStreamConfig::callback),
},
)
}

/// Configures the `user_input` stream.
pub fn with_user_input(self, user_input: InputStreamConfig) -> Self {
Self { user_input, ..self }
}

/// Configures the `user_output` stream.
pub fn with_user_output(self, user_output: OutputStreamConfig) -> Self {
Self {
user_output,
..self
}
}

/// Configures the `user_error` stream.
pub fn with_user_error(self, user_error: OutputStreamConfig) -> Self {
Self { user_error, ..self }
}

fn into_streams(self, arena: &mut Arena, add_history: bool) -> (Stream, Stream, Stream) {
(
self.stdin.into_stream(arena, add_history),
self.stdout.into_stream(arena),
self.stderr.into_stream(arena),
self.user_input.into_stream(arena, add_history),
self.user_output.into_stream(arena),
self.user_error.into_stream(arena),
)
}
}
Expand Down
20 changes: 6 additions & 14 deletions src/machine/streams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2075,10 +2075,8 @@ mod tests {
#[test]
#[cfg_attr(miri, ignore)]
fn user_input_string_stream() {
let streams = StreamConfig {
stdin: InputStreamConfig::string("a(1,2,3)."),
..Default::default()
};
let streams =
StreamConfig::default().with_user_input(InputStreamConfig::string("a(1,2,3)."));

let mut machine = MachineBuilder::default().with_streams(streams).build();

Expand Down Expand Up @@ -2107,11 +2105,7 @@ mod tests {
#[cfg_attr(miri, ignore)]
fn user_input_channel_stream() {
let (mut user_input, channel_stream) = InputStreamConfig::channel();
let streams = StreamConfig {
stdin: channel_stream,
..Default::default()
};

let streams = StreamConfig::default().with_user_input(channel_stream);
let mut machine = MachineBuilder::default().with_streams(streams).build();

let complete_answer: Vec<_> = machine
Expand Down Expand Up @@ -2167,15 +2161,13 @@ mod tests {
fn user_output_callback_stream() {
let test_string = Rc::new(RefCell::new(String::new()));

let streams = StreamConfig {
stdout: OutputStreamConfig::callback(Box::new({
let streams =
StreamConfig::default().with_user_output(OutputStreamConfig::callback(Box::new({
let test_string = test_string.clone();
move |x| {
x.read_to_string(&mut test_string.borrow_mut()).unwrap();
}
})),
..Default::default()
};
})));

let mut machine = MachineBuilder::default().with_streams(streams).build();

Expand Down

0 comments on commit ee8b7c4

Please sign in to comment.