Basic pipelining is working!

This commit is contained in:
Yehuda Katz
2019-05-15 11:12:38 -05:00
parent 975ff7c2fb
commit 3040638881
18 changed files with 405 additions and 239 deletions

32
src/parser/completer.rs Normal file
View File

@ -0,0 +1,32 @@
use rustyline::{completion, Context};
use std::collections::BTreeMap;
crate struct Completer {
commands: BTreeMap<String, Box<dyn crate::CommandBlueprint>>,
}
impl completion::Completer for Completer {
type Candidate = completion::Pair;
fn complete(
&self,
line: &str,
pos: usize,
ctx: &Context<'_>,
) -> rustyline::Result<(usize, Vec<completion::Pair>)> {
let pairs = self
.commands
.keys()
.map(|k| completion::Pair {
display: k.clone(),
replacement: k.clone(),
})
.collect();
Ok((0, pairs))
}
fn update(&self, line: &mut rustyline::line_buffer::LineBuffer, start: usize, elected: &str) {
let end = line.pos();
line.replace(start..end, elected)
}
}

82
src/parser/parse.rs Normal file
View File

@ -0,0 +1,82 @@
use crate::prelude::*;
use nom::branch::alt;
use nom::bytes::complete::{escaped, is_a, is_not, tag};
use nom::character::complete::one_of;
use nom::multi::separated_list;
use nom::sequence::{preceded, terminated};
use nom::IResult;
use nom::{complete, named, separated_list, ws};
use std::str::FromStr;
#[derive(Debug, Clone)]
pub enum Item {
Quoted(String),
Bare(String),
Int(i64),
}
impl Item {
crate fn as_value(&self) -> Value {
match self {
Item::Quoted(s) => Value::Primitive(Primitive::String(s.clone())),
Item::Bare(s) => Value::Primitive(Primitive::String(s.clone())),
Item::Int(i) => Value::Primitive(Primitive::Int(*i)),
}
}
}
crate fn print_items(items: &[Item]) -> String {
let mut out = String::new();
let formatted = items.iter().map(|item| match item {
Item::Bare(s) => format!("{}", s),
Item::Quoted(s) => format!("{:?}", s),
Item::Int(i) => format!("{:?}", i),
});
itertools::join(formatted, " ")
}
impl Item {
crate fn name(&self) -> &str {
match self {
Item::Quoted(s) => s,
Item::Bare(s) => s,
Item::Int(i) => unimplemented!(),
}
}
}
fn esc(s: &str) -> IResult<&str, &str> {
escaped(is_not("\\\""), '\\', one_of("\"n\\"))(s)
}
fn quoted(s: &str) -> IResult<&str, Item> {
terminated(preceded(tag("\""), esc), tag("\""))(s)
.map(|(a, b)| (a, Item::Quoted(b.to_string())))
}
fn unquoted(s: &str) -> IResult<&str, Item> {
is_not(" |")(s).map(|(a, b)| (a, Item::Bare(b.to_string())))
}
fn int(s: &str) -> IResult<&str, Item> {
is_a("1234567890")(s).map(|(a, b)| (a, Item::Int(FromStr::from_str(b).unwrap())))
}
fn command_token(s: &str) -> IResult<&str, Item> {
alt((int, quoted, unquoted))(s)
}
fn command_args(s: &str) -> IResult<&str, Vec<Item>> {
separated_list(tag(" "), command_token)(s)
}
named!(
pub shell_parser(&str) -> Vec<Vec<Item>>,
complete!(
ws!(
separated_list!(tag("|"), command_args)
)
)
);