Use custom Arc backed input
Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
parent
1ea15f0e49
commit
1ee7611981
6 changed files with 283 additions and 77 deletions
|
|
@ -31,9 +31,10 @@ use winnow::token::take_until;
|
|||
use winnow::token::take_while;
|
||||
|
||||
use crate::SourceSpan;
|
||||
use crate::input::TempleInput;
|
||||
use crate::resume_after_cut;
|
||||
|
||||
type Input<'input> = Recoverable<LocatingSlice<&'input str>, ParseError>;
|
||||
type Input<'input> = Recoverable<LocatingSlice<TempleInput>, ParseError>;
|
||||
type PResult<'input, T> = Result<T, ParseError>;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -177,12 +178,12 @@ impl<'input> ParserError<Input<'input>> for ParseError {
|
|||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ParsedTemplate<'input> {
|
||||
tokens: Vec<TemplateToken<'input>>,
|
||||
pub struct ParsedTemplate {
|
||||
tokens: Vec<TemplateToken>,
|
||||
}
|
||||
|
||||
impl<'input> ParsedTemplate<'input> {
|
||||
pub fn tokens(&self) -> &[TemplateToken<'input>] {
|
||||
impl ParsedTemplate {
|
||||
pub fn tokens(&self) -> &[TemplateToken] {
|
||||
&self.tokens
|
||||
}
|
||||
}
|
||||
|
|
@ -198,88 +199,86 @@ pub enum TokenKind {
|
|||
Invalid,
|
||||
}
|
||||
|
||||
impl PartialEq<TokenKind> for TemplateToken<'_> {
|
||||
impl PartialEq<TokenKind> for TemplateToken {
|
||||
fn eq(&self, other: &TokenKind) -> bool {
|
||||
self.kind == *other
|
||||
}
|
||||
}
|
||||
|
||||
impl winnow::stream::ContainsToken<&'_ TemplateToken<'_>> for TokenKind {
|
||||
fn contains_token(&self, token: &'_ TemplateToken<'_>) -> bool {
|
||||
impl winnow::stream::ContainsToken<&'_ TemplateToken> for TokenKind {
|
||||
fn contains_token(&self, token: &'_ TemplateToken) -> bool {
|
||||
*self == token.kind
|
||||
}
|
||||
}
|
||||
|
||||
impl winnow::stream::ContainsToken<&'_ TemplateToken<'_>> for &'_ [TokenKind] {
|
||||
fn contains_token(&self, token: &'_ TemplateToken<'_>) -> bool {
|
||||
impl winnow::stream::ContainsToken<&'_ TemplateToken> for &'_ [TokenKind] {
|
||||
fn contains_token(&self, token: &'_ TemplateToken) -> bool {
|
||||
self.contains(&token.kind)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEN: usize> winnow::stream::ContainsToken<&'_ TemplateToken<'_>>
|
||||
for &'_ [TokenKind; LEN]
|
||||
{
|
||||
fn contains_token(&self, token: &'_ TemplateToken<'_>) -> bool {
|
||||
impl<const LEN: usize> winnow::stream::ContainsToken<&'_ TemplateToken> for &'_ [TokenKind; LEN] {
|
||||
fn contains_token(&self, token: &'_ TemplateToken) -> bool {
|
||||
self.contains(&token.kind)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEN: usize> winnow::stream::ContainsToken<&'_ TemplateToken<'_>> for [TokenKind; LEN] {
|
||||
fn contains_token(&self, token: &'_ TemplateToken<'_>) -> bool {
|
||||
impl<const LEN: usize> winnow::stream::ContainsToken<&'_ TemplateToken> for [TokenKind; LEN] {
|
||||
fn contains_token(&self, token: &'_ TemplateToken) -> bool {
|
||||
self.contains(&token.kind)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct TemplateToken<'input> {
|
||||
pub struct TemplateToken {
|
||||
kind: TokenKind,
|
||||
source: &'input str,
|
||||
source: TempleInput,
|
||||
}
|
||||
|
||||
impl<'input> TemplateToken<'input> {
|
||||
fn content(source: &'input str) -> Self {
|
||||
impl TemplateToken {
|
||||
fn content(source: TempleInput) -> Self {
|
||||
TemplateToken {
|
||||
kind: TokenKind::Content,
|
||||
source,
|
||||
}
|
||||
}
|
||||
|
||||
fn left_delim(source: &'input str) -> Self {
|
||||
fn left_delim(source: TempleInput) -> Self {
|
||||
TemplateToken {
|
||||
kind: TokenKind::LeftDelim,
|
||||
source,
|
||||
}
|
||||
}
|
||||
|
||||
fn right_delim(source: &'input str) -> Self {
|
||||
fn right_delim(source: TempleInput) -> Self {
|
||||
TemplateToken {
|
||||
kind: TokenKind::RightDelim,
|
||||
source,
|
||||
}
|
||||
}
|
||||
|
||||
fn wants_output(source: &'input str) -> Self {
|
||||
fn wants_output(source: TempleInput) -> Self {
|
||||
TemplateToken {
|
||||
kind: TokenKind::WantsOutput,
|
||||
source,
|
||||
}
|
||||
}
|
||||
|
||||
fn ident(source: &'input str) -> Self {
|
||||
fn ident(source: TempleInput) -> Self {
|
||||
TemplateToken {
|
||||
kind: TokenKind::Ident,
|
||||
source,
|
||||
}
|
||||
}
|
||||
|
||||
fn whitespace(source: &'input str) -> Self {
|
||||
fn whitespace(source: TempleInput) -> Self {
|
||||
TemplateToken {
|
||||
kind: TokenKind::Whitespace,
|
||||
source,
|
||||
}
|
||||
}
|
||||
|
||||
fn invalid(source: &'input str) -> Self {
|
||||
fn invalid(source: TempleInput) -> Self {
|
||||
TemplateToken {
|
||||
kind: TokenKind::Invalid,
|
||||
source,
|
||||
|
|
@ -290,13 +289,14 @@ impl<'input> TemplateToken<'input> {
|
|||
self.kind
|
||||
}
|
||||
|
||||
pub fn source(&self) -> &'input str {
|
||||
self.source
|
||||
pub fn source(&self) -> TempleInput {
|
||||
self.source.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> Result<ParsedTemplate<'_>, ParseFailure> {
|
||||
let (_remaining, val, errors) = parse_tokens.recoverable_parse(LocatingSlice::new(input));
|
||||
pub fn parse(input: &str) -> Result<ParsedTemplate, ParseFailure> {
|
||||
let (_remaining, val, errors) =
|
||||
parse_tokens.recoverable_parse(LocatingSlice::new(TempleInput::from(input)));
|
||||
|
||||
if errors.is_empty()
|
||||
&& let Some(val) = val
|
||||
|
|
@ -307,13 +307,13 @@ pub fn parse(input: &str) -> Result<ParsedTemplate<'_>, ParseFailure> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_tokens<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<TemplateToken<'input>>> {
|
||||
fn parse_tokens<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<TemplateToken>> {
|
||||
repeat_till(0.., alt((parse_interpolate, parse_content)), eof)
|
||||
.map(|(v, _): (Vec<_>, _)| v.into_iter().flatten().collect())
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
fn parse_content<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<TemplateToken<'input>>> {
|
||||
fn parse_content<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<TemplateToken>> {
|
||||
alt((
|
||||
repeat_till(1.., any, peek((multispace0, "{{"))).map(|((), _)| ()),
|
||||
rest.void(),
|
||||
|
|
@ -324,9 +324,7 @@ fn parse_content<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<Templ
|
|||
.parse_next(input)
|
||||
}
|
||||
|
||||
fn parse_interpolate<'input>(
|
||||
input: &mut Input<'input>,
|
||||
) -> PResult<'input, Vec<TemplateToken<'input>>> {
|
||||
fn parse_interpolate<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<TemplateToken>> {
|
||||
let prev_whitespace = opt(parse_whitespace).parse_next(input)?;
|
||||
let left_delim = "{{".map(TemplateToken::left_delim).parse_next(input)?;
|
||||
let wants_output = opt("=".map(TemplateToken::wants_output)).parse_next(input)?;
|
||||
|
|
@ -337,7 +335,9 @@ fn parse_interpolate<'input>(
|
|||
let (inside_tokens, _): (Vec<_>, _) = get_tokens
|
||||
.resume_after(recover)
|
||||
.with_taken()
|
||||
.map(|(val, taken)| val.unwrap_or_else(|| (vec![TemplateToken::invalid(taken)], "")))
|
||||
.map(|(val, taken)| {
|
||||
val.unwrap_or_else(|| (vec![TemplateToken::invalid(taken)], TempleInput::from("")))
|
||||
})
|
||||
.parse_next(input)?;
|
||||
|
||||
let right_delim = "}}".map(TemplateToken::right_delim).parse_next(input)?;
|
||||
|
|
@ -354,9 +354,7 @@ fn parse_interpolate<'input>(
|
|||
Ok(tokens)
|
||||
}
|
||||
|
||||
fn parse_interpolate_token<'input>(
|
||||
input: &mut Input<'input>,
|
||||
) -> PResult<'input, TemplateToken<'input>> {
|
||||
fn parse_interpolate_token<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> {
|
||||
trace(
|
||||
"parse_interpolate_token",
|
||||
alt((parse_ident, parse_whitespace)),
|
||||
|
|
@ -364,7 +362,7 @@ fn parse_interpolate_token<'input>(
|
|||
.parse_next(input)
|
||||
}
|
||||
|
||||
fn parse_whitespace<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken<'input>> {
|
||||
fn parse_whitespace<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> {
|
||||
trace(
|
||||
"parse_whitespace",
|
||||
multispace1.map(TemplateToken::whitespace),
|
||||
|
|
@ -372,7 +370,7 @@ fn parse_whitespace<'input>(input: &mut Input<'input>) -> PResult<'input, Templa
|
|||
.parse_next(input)
|
||||
}
|
||||
|
||||
fn parse_ident<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken<'input>> {
|
||||
fn parse_ident<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateToken> {
|
||||
resume_after_cut(
|
||||
terminated(
|
||||
ident.map(TemplateToken::ident),
|
||||
|
|
@ -390,7 +388,7 @@ fn parse_ident<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateTok
|
|||
.parse_next(input)
|
||||
}
|
||||
|
||||
fn ident<'input>(input: &mut Input<'input>) -> PResult<'input, &'input str> {
|
||||
fn ident<'input>(input: &mut Input<'input>) -> PResult<'input, TempleInput> {
|
||||
take_while(1.., char::is_alphanumeric).parse_next(input)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue