Merge pull request #596 from Porges/improve-pipeline-parsing

Improve parsing of pipelines, require pipes between segments
This commit is contained in:
Yehuda Katz 2019-09-04 09:41:49 -07:00 committed by GitHub
commit fd715e1775
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 21 deletions

View file

@ -552,11 +552,11 @@ pub fn node(input: NomSpan) -> IResult<NomSpan, TokenNode> {
pub fn pipeline(input: NomSpan) -> IResult<NomSpan, TokenNode> {
trace_step(input, "pipeline", |input| {
let start = input.offset;
let (input, head) = opt(tuple((raw_call, opt(space1), opt(tag("|")))))(input)?;
let (input, head) = opt(tuple((opt(space1), raw_call, opt(space1))))(input)?;
let (input, items) = trace_step(
input,
"many0",
many0(tuple((opt(space1), raw_call, opt(space1), opt(tag("|"))))),
many0(tuple((tag("|"), opt(space1), raw_call, opt(space1)))),
)?;
let (input, tail) = opt(space1)(input)?;
@ -582,28 +582,37 @@ pub fn pipeline(input: NomSpan) -> IResult<NomSpan, TokenNode> {
}
fn make_call_list(
head: Option<(Tagged<CallNode>, Option<NomSpan>, Option<NomSpan>)>,
items: Vec<(
head: Option<(
Option<NomSpan>,
Tagged<CallNode>,
Option<NomSpan>
)>,
items: Vec<(
NomSpan,
Option<NomSpan>,
Tagged<CallNode>,
Option<NomSpan>,
)>,
) -> Vec<PipelineElement> {
let mut out = vec![];
if let Some(head) = head {
let el = PipelineElement::new(None, head.0, head.1.map(Span::from), head.2.map(Span::from));
let el = PipelineElement::new(
None,
head.0.map(Span::from),
head.1,
head.2.map(Span::from));
out.push(el);
}
for (ws1, call, ws2, pipe) in items {
for (pipe, ws1, call, ws2) in items {
let el = PipelineElement::new(
Some(pipe).map(Span::from),
ws1.map(Span::from),
call,
ws2.map(Span::from),
pipe.map(Span::from),
);
ws2.map(Span::from));
out.push(el);
}

View file

@ -11,9 +11,9 @@ pub struct Pipeline {
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Getters, new)]
pub struct PipelineElement {
pub pipe: Option<Span>,
pub pre_ws: Option<Span>,
#[get = "pub(crate)"]
call: Tagged<CallNode>,
pub post_ws: Option<Span>,
pub post_pipe: Option<Span>,
}

View file

@ -47,32 +47,31 @@ impl TokenTreeBuilder {
.next()
.expect("A pipeline must contain at least one element");
let pipe = None;
let pre_span = pre.map(|pre| b.consume(&pre));
let call = call(b);
let post_span = post.map(|post| b.consume(&post));
let pipe = input.peek().map(|_| Span::from(b.consume("|")));
out.push(PipelineElement::new(
pipe,
pre_span.map(Span::from),
call,
post_span.map(Span::from),
pipe,
));
post_span.map(Span::from)));
loop {
match input.next() {
None => break,
Some((pre, call, post)) => {
let pipe = Some(Span::from(b.consume("|")));
let pre_span = pre.map(|pre| b.consume(&pre));
let call = call(b);
let post_span = post.map(|post| b.consume(&post));
let pipe = input.peek().map(|_| Span::from(b.consume("|")));
out.push(PipelineElement::new(
pipe,
pre_span.map(Span::from),
call,
post_span.map(Span::from),
pipe,
));
}
}

View file

@ -147,6 +147,10 @@ fn paint_token_node(token_node: &TokenNode, line: &str) -> String {
fn paint_pipeline_element(pipeline_element: &PipelineElement, line: &str) -> String {
let mut styled = String::new();
if let Some(_) = pipeline_element.pipe {
styled.push_str(&Color::Purple.paint("|"));
}
if let Some(ws) = pipeline_element.pre_ws {
styled.push_str(&Color::White.normal().paint(ws.slice(line)));
}
@ -168,10 +172,6 @@ fn paint_pipeline_element(pipeline_element: &PipelineElement, line: &str) -> Str
styled.push_str(&Color::White.normal().paint(ws.slice(line)));
}
if let Some(_) = pipeline_element.post_pipe {
styled.push_str(&Color::Purple.paint("|"));
}
styled.to_string()
}