#[macro_use]
extern crate rustupolis;
mod lexing;
use std::io;
use std::io::Write;
use futures::executor;
use lexing::Lexer;
use rustupolis::space::Space;
use rustupolis::store::SimpleStore;
use rustupolis::tuple::Tuple;
fn main() {
println!("Rustupolis CLI");
let mut cli = Cli::new(io::stdin(), io::stdout());
cli.run()
}
enum RequiredAction {
CLOSE,
DETACH,
NONE,
}
struct Cli {
stdin: io::Stdin,
stdout: io::Stdout,
tuplespace: Option<Space<SimpleStore>>,
}
impl Cli {
fn new(stdin: io::Stdin, stdout: io::Stdout) -> Cli {
Cli {
stdin,
stdout,
tuplespace: None,
}
}
fn run(&mut self) {
use self::RequiredAction::*;
let mut input = String::new();
loop {
print!("> ");
self.stdout.flush().expect("failed to flush stdout");
self.stdin
.read_line(&mut input)
.expect("failed to read input");
let required_action = self.process_input(input.trim());
input.clear();
match required_action {
CLOSE => break,
DETACH => break,
NONE => {}
}
}
}
fn process_input(&mut self, input: &str) -> RequiredAction {
use self::RequiredAction::*;
println!("user echo: {}", input);
let tokens: Vec<&str> = input.trim().split_whitespace().collect();
if tokens.is_empty() {
return NONE;
}
let command = tokens.get(0);
match command {
Some(&"create") => self.cmd_create(&tokens[1..]),
Some(&"close") => self.cmd_close(),
Some(&"detach") => self.cmd_detach(),
Some(&"out") => self.cmd_tuple_out(&tokens[1..]),
Some(&"read") | Some(&"rd") => self.cmd_tuple_read(&tokens[1..]),
Some(&"take") | Some(&"in") => self.cmd_tuple_take(&tokens[1..]),
_ => {
println!("unknown command");
NONE
}
}
}
fn cmd_create(&mut self, parameters: &[&str]) -> RequiredAction {
println!("creation parameters:");
for p in parameters {
println!("{}", p)
}
if self.tuplespace.is_none() {
println!("creating new tuplespace");
self.tuplespace = Some(Space::new(SimpleStore::new()));
} else {
println!("cannot create new tuple space! already exists");
}
RequiredAction::NONE
}
fn cmd_close(&mut self) -> RequiredAction {
RequiredAction::CLOSE
}
fn cmd_detach(&mut self) -> RequiredAction {
if self.tuplespace.is_none() {
println!("Cannot detach! Error: no tuple space initialised");
return RequiredAction::NONE;
}
RequiredAction::DETACH
}
fn cmd_tuple_out(&mut self, parameters: &[&str]) -> RequiredAction {
if let Some(space) = &mut self.tuplespace {
let param_list = parameters.join(" ");
let tuples: Vec<Tuple> = Lexer::new(¶m_list).collect();
for t in tuples {
if !t.is_empty() {
if t.is_defined() {
if let Err(e) = executor::block_on(space.tuple_out(t)) {
eprintln!("Cannot push tuple into space! Encountered error {:?}", e);
} else {
println!("pushed tuple(s) {} into tuple space", param_list);
}
} else {
eprintln!("Cannot push tuple into space! The given tuple is ill-defined.");
}
}
}
} else {
println!("Cannot push tuple into space! There is no tuple space initialised");
}
RequiredAction::NONE
}
fn cmd_tuple_read(&mut self, parameters: &[&str]) -> RequiredAction {
if let Some(space) = &mut self.tuplespace {
let param_list = parameters.join(" ");
let tuples: Vec<Tuple> = Lexer::new(¶m_list).collect();
for rd_tup in tuples {
if !rd_tup.is_empty() {
println!("reading tuple matching {} from space", rd_tup);
if let Some(match_tup) = executor::block_on(space.tuple_rd(rd_tup)) {
if match_tup.is_empty() {
eprintln!("No matching tuple could be found.");
} else {
println!("found match: {}", match_tup);
}
}
}
}
} else {
println!("Cannot read tuple from space! There is no tuple space initialised");
}
RequiredAction::NONE
}
fn cmd_tuple_take(&mut self, parameters: &[&str]) -> RequiredAction {
if let Some(space) = &mut self.tuplespace {
let param_list = parameters.join(" ");
let tuples: Vec<Tuple> = Lexer::new(¶m_list).collect();
for rd_tup in tuples {
if !rd_tup.is_empty() {
println!("pulling in tuple matching {} from space", rd_tup);
if let Some(match_tup) = executor::block_on(space.tuple_in(rd_tup)) {
if match_tup.is_empty() {
eprintln!("No matching tuple could be found.");
} else {
println!("found match: {}", match_tup);
}
}
}
}
} else {
println!("Cannot pull in tuple from space! There is no tuple space initialised");
}
RequiredAction::NONE
}
}