-pub struct MachineConfig {
- pub streams: StreamConfig,
- pub toplevel: &'static str,
+/// Describes how the streams of a `crate::Machine` will be handled.
+///
+/// Defaults to using standard IO.
+pub struct StreamConfig {
+ pub(crate) inner: StreamConfigInner,
+}
+
+impl Default for StreamConfig {
+ fn default() -> Self {
+ Self::stdio()
+ }
+}
+
+impl StreamConfig {
+ /// Binds the input, output and error streams to stdin, stdout and stderr.
+ pub fn stdio() -> Self {
+ StreamConfig {
+ inner: StreamConfigInner::Stdio,
+ }
+ }
+
+ /// Binds the output stream to a memory buffer, and the error stream to stderr.
+ ///
+ /// The input stream is ignored.
+ pub fn in_memory() -> Self {
+ StreamConfig {
+ inner: StreamConfigInner::Memory,
+ }
+ }
}
-pub enum StreamConfig {
+pub(crate) enum StreamConfigInner {
Stdio,
Memory,
}
+/// Describes how a `crate::Machine` will be configured.
+pub struct MachineConfig {
+ pub(crate) streams: StreamConfig,
+ pub(crate) toplevel: &'static str,
+}
+
impl Default for MachineConfig {
fn default() -> Self {
MachineConfig {
- streams: StreamConfig::Stdio,
- toplevel: include_str!("../toplevel.pl"),
+ streams: Default::default(),
+ toplevel: default_toplevel(),
}
}
}
impl MachineConfig {
- pub fn in_memory() -> Self {
- MachineConfig {
- streams: StreamConfig::Memory,
- ..Default::default()
- }
+ /// Creates a default configuration.
+ pub fn new() -> Self {
+ Default::default()
+ }
+
+ /// Uses the given `crate::StreamConfig` in this configuration.
+ pub fn with_streams(mut self, streams: StreamConfig) -> Self {
+ self.streams = streams;
+ self
}
+ /// Uses the given toplevel in this configuration.
pub fn with_toplevel(mut self, toplevel: &'static str) -> Self {
self.toplevel = toplevel;
self
}
}
+
+/// Returns a static string slice to the default toplevel
+pub fn default_toplevel() -> &'static str {
+ include_str!("../toplevel.pl")
+}
use std::collections::BTreeMap;
-use crate::atom_table;
+use crate::{atom_table, StreamConfig};
use crate::machine::machine_indices::VarKey;
use crate::machine::mock_wam::CompositeOpDir;
use crate::machine::{BREAK_FROM_DISPATCH_LOOP_LOC, LIB_QUERY_SUCCESS};
impl Machine {
pub fn new_lib() -> Self {
- Machine::new(MachineConfig::in_memory())
+ Machine::new(MachineConfig::default().with_streams(StreamConfig::in_memory()))
}
pub fn load_module_string(&mut self, module_name: &str, program: String) {
let args = MachineArgs::new();
let mut machine_st = MachineState::new();
- let (user_input, user_output, user_error) = match config.streams {
- config::StreamConfig::Stdio => (
+ let (user_input, user_output, user_error) = match config.streams.inner {
+ config::StreamConfigInner::Stdio => (
Stream::stdin(&mut machine_st.arena, args.add_history),
Stream::stdout(&mut machine_st.arena),
Stream::stderr(&mut machine_st.arena),
),
- config::StreamConfig::Memory => (
+ config::StreamConfigInner::Memory => (
Stream::Null(StreamOptions::default()),
Stream::from_owned_string("".to_owned(), &mut machine_st.arena),
Stream::stderr(&mut machine_st.arena),