1
Fork 0

suggest a positional formatting argument instead of a captured argument

This commit is contained in:
Takayuki Maeda 2022-08-02 20:33:40 +09:00
parent e4417cf020
commit 4233a13ceb
5 changed files with 148 additions and 15 deletions

View file

@ -175,6 +175,7 @@ pub struct ParseError {
pub label: string::String,
pub span: InnerSpan,
pub secondary_label: Option<(string::String, InnerSpan)>,
pub should_be_replaced_with_positional_argument: bool,
}
/// The parser structure for interpreting the input format string. This is
@ -228,13 +229,19 @@ impl<'a> Iterator for Parser<'a> {
Some(String(self.string(pos + 1)))
} else {
let arg = self.argument(lbrace_end);
if let Some(rbrace_byte_idx) = self.must_consume('}') {
let lbrace_inner_offset = self.to_span_index(pos);
let rbrace_inner_offset = self.to_span_index(rbrace_byte_idx);
if self.is_literal {
self.arg_places.push(
lbrace_inner_offset.to(InnerOffset(rbrace_inner_offset.0 + 1)),
);
match self.must_consume('}') {
Some(rbrace_byte_idx) => {
let lbrace_inner_offset = self.to_span_index(pos);
let rbrace_inner_offset = self.to_span_index(rbrace_byte_idx);
if self.is_literal {
self.arg_places.push(
lbrace_inner_offset
.to(InnerOffset(rbrace_inner_offset.0 + 1)),
);
}
}
None => {
self.suggest_positional_arg_instead_of_captured_arg(arg);
}
}
Some(NextArgument(arg))
@ -313,6 +320,7 @@ impl<'a> Parser<'a> {
label: label.into(),
span,
secondary_label: None,
should_be_replaced_with_positional_argument: false,
});
}
@ -336,6 +344,7 @@ impl<'a> Parser<'a> {
label: label.into(),
span,
secondary_label: None,
should_be_replaced_with_positional_argument: false,
});
}
@ -407,6 +416,7 @@ impl<'a> Parser<'a> {
label,
span: pos.to(pos),
secondary_label,
should_be_replaced_with_positional_argument: false,
});
None
}
@ -434,6 +444,7 @@ impl<'a> Parser<'a> {
label,
span: pos.to(pos),
secondary_label,
should_be_replaced_with_positional_argument: false,
});
} else {
self.err(description, format!("expected `{:?}`", c), pos.to(pos));
@ -750,6 +761,29 @@ impl<'a> Parser<'a> {
}
if found { Some(cur) } else { None }
}
fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>) {
if let Some(end) = self.consume_pos('.') {
let byte_pos = self.to_span_index(end);
let start = InnerOffset(byte_pos.0 + 1);
let field = self.argument(start);
if let ArgumentNamed(_) = arg.position {
if let ArgumentNamed(_) = field.position {
self.errors.insert(
0,
ParseError {
description: "field access isn't supported".to_string(),
note: None,
label: "not supported".to_string(),
span: InnerSpan::new(arg.position_span.start, field.position_span.end),
secondary_label: None,
should_be_replaced_with_positional_argument: true,
},
);
}
}
}
}
}
/// Finds the indices of all characters that have been processed and differ between the actual