Current section

Files

Jump to
liquex lib liquex parser field.ex
Raw

lib/liquex/parser/field.ex

defmodule Liquex.Parser.Field do
@moduledoc false
import NimbleParsec
alias Liquex.Parser.Argument
alias Liquex.Parser.Literal
@spec identifier(NimbleParsec.t()) :: NimbleParsec.t()
def identifier(combinator \\ empty()) do
# Identifiers can start with any letter or underscore.
# - The remaining characters can include digits
# - May end in a question mark (?)
combinator
|> utf8_string([?a..?z, ?A..?Z, ?_], 1)
|> concat(utf8_string([?a..?z, ?A..?Z, ?0..?9, ?_], min: 0))
|> concat(optional(string("?")))
|> reduce({Enum, :join, []})
end
@spec accessor(NimbleParsec.t()) :: NimbleParsec.t()
def accessor(combinator \\ empty()) do
combinator
|> ignore(string("["))
|> ignore(Literal.whitespace())
|> Argument.argument()
|> ignore(Literal.whitespace())
|> ignore(string("]"))
|> unwrap_and_tag(:accessor)
end
@spec key_access(NimbleParsec.t()) :: NimbleParsec.t()
def key_access(combinator \\ empty()) do
combinator
|> ignore(string("."))
|> identifier()
|> unwrap_and_tag(:key)
end
@spec field(NimbleParsec.t()) :: NimbleParsec.t()
def field(combinator \\ empty()) do
combinator
|> identifier()
|> unwrap_and_tag(:key)
|> repeat(
choice([
accessor(),
key_access()
])
)
|> tag(:field)
end
end