Fix fields being parsed as idioms. (#4819)
This commit is contained in:
parent
5867ce95d9
commit
52aef7ccc4
13 changed files with 100 additions and 85 deletions
|
@ -64,7 +64,7 @@ pub fn value(input: &str) -> Result<Value, Error> {
|
|||
.with_query_recursion_limit(*MAX_QUERY_PARSING_DEPTH as usize);
|
||||
let mut stack = Stack::new();
|
||||
stack
|
||||
.enter(|stk| parser.parse_value_table(stk))
|
||||
.enter(|stk| parser.parse_value_field(stk))
|
||||
.finish()
|
||||
.and_then(|e| parser.assert_finished().map(|_| e))
|
||||
.map_err(|e| e.render_on(input))
|
||||
|
@ -211,7 +211,7 @@ pub fn value_legacy_strand(input: &str) -> Result<Value, Error> {
|
|||
let mut stack = Stack::new();
|
||||
parser.allow_legacy_strand(true);
|
||||
stack
|
||||
.enter(|stk| parser.parse_value_table(stk))
|
||||
.enter(|stk| parser.parse_value_field(stk))
|
||||
.finish()
|
||||
.and_then(|e| parser.assert_finished().map(|_| e))
|
||||
.map_err(|e| e.render_on(input))
|
||||
|
|
|
@ -188,6 +188,7 @@ impl Parser<'_> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::sql::{Ident, Part};
|
||||
|
||||
#[test]
|
||||
fn identifiers() {
|
||||
|
@ -206,8 +207,8 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
r,
|
||||
sql::Query(sql::Statements(vec![sql::Statement::Value(sql::Value::Table(
|
||||
sql::Table(ident.to_string())
|
||||
sql::Query(sql::Statements(vec![sql::Statement::Value(sql::Value::Idiom(
|
||||
sql::Idiom(vec![Part::Field(Ident(ident.to_string()))])
|
||||
))]))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ impl<'a> Parser<'a> {
|
|||
last_span: Span::empty(),
|
||||
token_buffer: TokenBuffer::new(),
|
||||
glued_value: GluedValue::None,
|
||||
table_as_field: false,
|
||||
table_as_field: true,
|
||||
legacy_strands: false,
|
||||
flexible_record_id: true,
|
||||
object_recursion: 100,
|
||||
|
@ -180,7 +180,7 @@ impl<'a> Parser<'a> {
|
|||
pub fn reset(&mut self) {
|
||||
self.last_span = Span::empty();
|
||||
self.token_buffer.clear();
|
||||
self.table_as_field = false;
|
||||
self.table_as_field = true;
|
||||
self.lexer.reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -335,12 +335,12 @@ impl Parser<'_> {
|
|||
t!("SIGNUP") => {
|
||||
self.pop_peek();
|
||||
ac.signup =
|
||||
Some(stk.run(|stk| self.parse_value_table(stk)).await?);
|
||||
Some(stk.run(|stk| self.parse_value_field(stk)).await?);
|
||||
}
|
||||
t!("SIGNIN") => {
|
||||
self.pop_peek();
|
||||
ac.signin =
|
||||
Some(stk.run(|stk| self.parse_value_table(stk)).await?);
|
||||
Some(stk.run(|stk| self.parse_value_field(stk)).await?);
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
|
@ -375,7 +375,7 @@ impl Parser<'_> {
|
|||
}
|
||||
t!("AUTHENTICATE") => {
|
||||
self.pop_peek();
|
||||
res.authenticate = Some(stk.run(|stk| self.parse_value_table(stk)).await?);
|
||||
res.authenticate = Some(stk.run(|stk| self.parse_value_field(stk)).await?);
|
||||
}
|
||||
t!("DURATION") => {
|
||||
self.pop_peek();
|
||||
|
@ -581,11 +581,11 @@ impl Parser<'_> {
|
|||
}
|
||||
t!("SIGNUP") => {
|
||||
self.pop_peek();
|
||||
ac.signup = Some(stk.run(|stk| self.parse_value_table(stk)).await?);
|
||||
ac.signup = Some(stk.run(|stk| self.parse_value_field(stk)).await?);
|
||||
}
|
||||
t!("SIGNIN") => {
|
||||
self.pop_peek();
|
||||
ac.signin = Some(stk.run(|stk| self.parse_value_table(stk)).await?);
|
||||
ac.signin = Some(stk.run(|stk| self.parse_value_field(stk)).await?);
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
|
@ -619,7 +619,7 @@ impl Parser<'_> {
|
|||
match self.peek_kind() {
|
||||
t!("VALUE") => {
|
||||
self.pop_peek();
|
||||
res.value = ctx.run(|ctx| self.parse_value_table(ctx)).await?;
|
||||
res.value = ctx.run(|ctx| self.parse_value_field(ctx)).await?;
|
||||
}
|
||||
t!("COMMENT") => {
|
||||
self.pop_peek();
|
||||
|
@ -758,13 +758,13 @@ impl Parser<'_> {
|
|||
match self.peek_kind() {
|
||||
t!("WHEN") => {
|
||||
self.pop_peek();
|
||||
res.when = ctx.run(|ctx| self.parse_value_table(ctx)).await?;
|
||||
res.when = ctx.run(|ctx| self.parse_value_field(ctx)).await?;
|
||||
}
|
||||
t!("THEN") => {
|
||||
self.pop_peek();
|
||||
res.then = Values(vec![ctx.run(|ctx| self.parse_value_table(ctx)).await?]);
|
||||
res.then = Values(vec![ctx.run(|ctx| self.parse_value_field(ctx)).await?]);
|
||||
while self.eat(t!(",")) {
|
||||
res.then.0.push(ctx.run(|ctx| self.parse_value_table(ctx)).await?)
|
||||
res.then.0.push(ctx.run(|ctx| self.parse_value_field(ctx)).await?)
|
||||
}
|
||||
}
|
||||
t!("COMMENT") => {
|
||||
|
|
|
@ -129,7 +129,7 @@ impl Parser<'_> {
|
|||
let mut values = Vec::new();
|
||||
let start = expected!(self, t!("(")).span;
|
||||
loop {
|
||||
values.push(self.parse_value_table(ctx).await?);
|
||||
values.push(self.parse_value_field(ctx).await?);
|
||||
|
||||
if !self.eat(t!(",")) {
|
||||
break;
|
||||
|
|
|
@ -214,7 +214,7 @@ impl Parser<'_> {
|
|||
}
|
||||
_ => {
|
||||
// TODO: Provide information about keywords.
|
||||
let value = ctx.run(|ctx| self.parse_value_table(ctx)).await?;
|
||||
let value = ctx.run(|ctx| self.parse_value_field(ctx)).await?;
|
||||
Ok(Self::refine_stmt_value(value))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,14 @@ impl Parser<'_> {
|
|||
}
|
||||
}
|
||||
pub async fn parse_relate_value(&mut self, ctx: &mut Stk) -> ParseResult<Value> {
|
||||
let old = self.table_as_field;
|
||||
self.table_as_field = true;
|
||||
let r = self.parse_relate_value_inner(ctx).await;
|
||||
self.table_as_field = old;
|
||||
r
|
||||
}
|
||||
|
||||
async fn parse_relate_value_inner(&mut self, ctx: &mut Stk) -> ParseResult<Value> {
|
||||
match self.peek_kind() {
|
||||
t!("[") => {
|
||||
let start = self.pop_peek().span;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
sql::{self, Id, Statement, Thing, Value},
|
||||
sql::{self, Id, Ident, Idiom, Part, Query, Statement, Statements, Thing, Value},
|
||||
syn::parser::mac::test_parse,
|
||||
};
|
||||
|
||||
|
@ -83,6 +83,20 @@ fn query_object() {
|
|||
test_parse!(parse_query, src).inspect_err(|e| eprintln!("{}", e.render_on(src))).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ident_is_field() {
|
||||
let src = r#"foo"#;
|
||||
|
||||
let field =
|
||||
test_parse!(parse_query, src).inspect_err(|e| eprintln!("{}", e.render_on(src))).unwrap();
|
||||
assert_eq!(
|
||||
field,
|
||||
Query(Statements(vec![Statement::Value(Value::Idiom(Idiom(vec![Part::Field(Ident(
|
||||
"foo".to_string()
|
||||
))])))]))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escaped_params_backtick() {
|
||||
test_parse!(
|
||||
|
|
|
@ -41,6 +41,10 @@ use crate::{
|
|||
};
|
||||
use chrono::{offset::TimeZone, NaiveDate, Offset, Utc};
|
||||
|
||||
fn ident_field(name: &str) -> Value {
|
||||
Value::Idiom(Idiom(vec![Part::Field(Ident(name.to_string()))]))
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn parse_analyze() {
|
||||
let res = test_parse!(parse_stmt, r#"ANALYZE INDEX b on a"#).unwrap();
|
||||
|
@ -205,7 +209,7 @@ fn parse_define_function() {
|
|||
(Ident("b".to_string()), Kind::Array(Box::new(Kind::Bool), Some(3)))
|
||||
],
|
||||
block: Block(vec![Entry::Output(OutputStatement {
|
||||
what: Value::Table(Table("a".to_string())),
|
||||
what: ident_field("a"),
|
||||
fetch: None,
|
||||
})]),
|
||||
comment: Some(Strand("test".to_string())),
|
||||
|
@ -1709,10 +1713,10 @@ fn parse_if() {
|
|||
res,
|
||||
Statement::Ifelse(IfelseStatement {
|
||||
exprs: vec![
|
||||
(Value::Table(Table("foo".to_owned())), Value::Table(Table("bar".to_owned()))),
|
||||
(Value::Table(Table("faz".to_owned())), Value::Table(Table("baz".to_owned())))
|
||||
(ident_field("foo"), ident_field("bar")),
|
||||
(ident_field("faz"), ident_field("baz")),
|
||||
],
|
||||
close: Some(Value::Table(Table("baq".to_owned())))
|
||||
close: Some(ident_field("baq"))
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -1726,21 +1730,15 @@ fn parse_if_block() {
|
|||
Statement::Ifelse(IfelseStatement {
|
||||
exprs: vec![
|
||||
(
|
||||
Value::Table(Table("foo".to_owned())),
|
||||
Value::Block(Box::new(Block(vec![Entry::Value(Value::Table(Table(
|
||||
"bar".to_owned()
|
||||
)),)]))),
|
||||
ident_field("foo"),
|
||||
Value::Block(Box::new(Block(vec![Entry::Value(ident_field("bar"))]))),
|
||||
),
|
||||
(
|
||||
Value::Table(Table("faz".to_owned())),
|
||||
Value::Block(Box::new(Block(vec![Entry::Value(Value::Table(Table(
|
||||
"baz".to_owned()
|
||||
)),)]))),
|
||||
ident_field("faz"),
|
||||
Value::Block(Box::new(Block(vec![Entry::Value(ident_field("baz"))]))),
|
||||
)
|
||||
],
|
||||
close: Some(Value::Block(Box::new(Block(vec![Entry::Value(Value::Table(Table(
|
||||
"baq".to_owned()
|
||||
)))])))),
|
||||
close: Some(Value::Block(Box::new(Block(vec![Entry::Value(ident_field("baq"))])))),
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -2193,10 +2191,8 @@ fn parse_return() {
|
|||
assert_eq!(
|
||||
res,
|
||||
Statement::Output(OutputStatement {
|
||||
what: Value::Table(Table("RETRUN".to_owned())),
|
||||
fetch: Some(Fetchs(vec![Fetch(Value::Idiom(Idiom(vec![Part::Field(
|
||||
Ident("RETURN".to_owned()).to_owned()
|
||||
)])))])),
|
||||
what: ident_field("RETRUN"),
|
||||
fetch: Some(Fetchs(vec![Fetch(ident_field("RETURN"))]))
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -31,6 +31,10 @@ use crate::{
|
|||
use chrono::{offset::TimeZone, NaiveDate, Offset, Utc};
|
||||
use reblessive::Stack;
|
||||
|
||||
fn ident_field(name: &str) -> Value {
|
||||
Value::Idiom(Idiom(vec![Part::Field(Ident(name.to_string()))]))
|
||||
}
|
||||
|
||||
static SOURCE: &str = r#"
|
||||
ANALYZE INDEX b on a;
|
||||
BEGIN;
|
||||
|
@ -192,7 +196,7 @@ fn statements() -> Vec<Statement> {
|
|||
(Ident("b".to_string()), Kind::Array(Box::new(Kind::Bool), Some(3))),
|
||||
],
|
||||
block: Block(vec![Entry::Output(OutputStatement {
|
||||
what: Value::Table(Table("a".to_string())),
|
||||
what: ident_field("a"),
|
||||
fetch: None,
|
||||
})]),
|
||||
comment: Some(Strand("test".to_string())),
|
||||
|
@ -440,29 +444,23 @@ fn statements() -> Vec<Statement> {
|
|||
}),
|
||||
Statement::Ifelse(IfelseStatement {
|
||||
exprs: vec![
|
||||
(Value::Table(Table("foo".to_owned())), Value::Table(Table("bar".to_owned()))),
|
||||
(Value::Table(Table("faz".to_owned())), Value::Table(Table("baz".to_owned()))),
|
||||
(ident_field("foo"), ident_field("bar")),
|
||||
(ident_field("faz"), ident_field("baz")),
|
||||
],
|
||||
close: Some(Value::Table(Table("baq".to_owned()))),
|
||||
close: Some(ident_field("baq")),
|
||||
}),
|
||||
Statement::Ifelse(IfelseStatement {
|
||||
exprs: vec![
|
||||
(
|
||||
Value::Table(Table("foo".to_owned())),
|
||||
Value::Block(Box::new(Block(vec![Entry::Value(Value::Table(Table(
|
||||
"bar".to_owned(),
|
||||
)))]))),
|
||||
ident_field("foo"),
|
||||
Value::Block(Box::new(Block(vec![Entry::Value(ident_field("bar"))]))),
|
||||
),
|
||||
(
|
||||
Value::Table(Table("faz".to_owned())),
|
||||
Value::Block(Box::new(Block(vec![Entry::Value(Value::Table(Table(
|
||||
"baz".to_owned(),
|
||||
)))]))),
|
||||
ident_field("faz"),
|
||||
Value::Block(Box::new(Block(vec![Entry::Value(ident_field("baz"))]))),
|
||||
),
|
||||
],
|
||||
close: Some(Value::Block(Box::new(Block(vec![Entry::Value(Value::Table(Table(
|
||||
"baq".to_owned(),
|
||||
)))])))),
|
||||
close: Some(Value::Block(Box::new(Block(vec![Entry::Value(ident_field("baq"))])))),
|
||||
}),
|
||||
Statement::Info(InfoStatement::Root(false)),
|
||||
Statement::Info(InfoStatement::Ns(false)),
|
||||
|
@ -606,10 +604,8 @@ fn statements() -> Vec<Statement> {
|
|||
id: Value::Uuid(Uuid(uuid::uuid!("e72bee20-f49b-11ec-b939-0242ac120002"))),
|
||||
}),
|
||||
Statement::Output(OutputStatement {
|
||||
what: Value::Table(Table("RETRUN".to_owned())),
|
||||
fetch: Some(Fetchs(vec![Fetch(Value::Idiom(Idiom(vec![Part::Field(
|
||||
Ident("RETURN".to_owned()).to_owned(),
|
||||
)])))])),
|
||||
what: ident_field("RETRUN"),
|
||||
fetch: Some(Fetchs(vec![Fetch(ident_field("RETURN"))])),
|
||||
}),
|
||||
Statement::Relate(RelateStatement {
|
||||
only: true,
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
|||
|
||||
#[test]
|
||||
fn parse_index_expression() {
|
||||
let value = test_parse!(parse_value_table, "a[1 + 1]").unwrap();
|
||||
let value = test_parse!(parse_value_field, "a[1 + 1]").unwrap();
|
||||
let Value::Idiom(x) = value else {
|
||||
panic!("not the right value type");
|
||||
};
|
||||
|
@ -29,7 +29,7 @@ fn parse_index_expression() {
|
|||
|
||||
#[test]
|
||||
fn parse_coordinate() {
|
||||
let coord = test_parse!(parse_value_table, "(1.88, -18.0)").unwrap();
|
||||
let coord = test_parse!(parse_value_field, "(1.88, -18.0)").unwrap();
|
||||
let Value::Geometry(Geometry::Point(x)) = coord else {
|
||||
panic!("not the right value");
|
||||
};
|
||||
|
@ -39,12 +39,12 @@ fn parse_coordinate() {
|
|||
|
||||
#[test]
|
||||
fn parse_like_operator() {
|
||||
test_parse!(parse_value_table, "a ~ b").unwrap();
|
||||
test_parse!(parse_value_field, "a ~ b").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_range_operator() {
|
||||
test_parse!(parse_value_table, "1..2").unwrap();
|
||||
test_parse!(parse_value_field, "1..2").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -116,7 +116,7 @@ fn parse_large_depth_record_id() {
|
|||
|
||||
#[test]
|
||||
fn parse_recursive_record_string() {
|
||||
let res = test_parse!(parse_value_table, r#" r"a:[r"b:{c: r"d:1"}"]" "#).unwrap();
|
||||
let res = test_parse!(parse_value_field, r#" r"a:[r"b:{c: r"d:1"}"]" "#).unwrap();
|
||||
assert_eq!(
|
||||
res,
|
||||
Value::Thing(Thing {
|
||||
|
@ -137,7 +137,7 @@ fn parse_recursive_record_string() {
|
|||
|
||||
#[test]
|
||||
fn parse_record_string_2() {
|
||||
let res = test_parse!(parse_value_table, r#" r'a:["foo"]' "#).unwrap();
|
||||
let res = test_parse!(parse_value_field, r#" r'a:["foo"]' "#).unwrap();
|
||||
assert_eq!(
|
||||
res,
|
||||
Value::Thing(Thing {
|
||||
|
@ -149,82 +149,82 @@ fn parse_record_string_2() {
|
|||
|
||||
#[test]
|
||||
fn parse_i64() {
|
||||
let res = test_parse!(parse_value_table, r#" -9223372036854775808 "#).unwrap();
|
||||
let res = test_parse!(parse_value_field, r#" -9223372036854775808 "#).unwrap();
|
||||
assert_eq!(res, Value::Number(Number::Int(i64::MIN)));
|
||||
|
||||
let res = test_parse!(parse_value_table, r#" 9223372036854775807 "#).unwrap();
|
||||
let res = test_parse!(parse_value_field, r#" 9223372036854775807 "#).unwrap();
|
||||
assert_eq!(res, Value::Number(Number::Int(i64::MAX)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn constant_lowercase() {
|
||||
let out = test_parse!(parse_value_table, r#" math::pi "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" math::pi "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::MathPi));
|
||||
|
||||
let out = test_parse!(parse_value_table, r#" math::inf "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" math::inf "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::MathInf));
|
||||
|
||||
let out = test_parse!(parse_value_table, r#" math::neg_inf "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" math::neg_inf "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::MathNegInf));
|
||||
|
||||
let out = test_parse!(parse_value_table, r#" time::epoch "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" time::epoch "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::TimeEpoch));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn constant_uppercase() {
|
||||
let out = test_parse!(parse_value_table, r#" MATH::PI "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" MATH::PI "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::MathPi));
|
||||
|
||||
let out = test_parse!(parse_value_table, r#" MATH::INF "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" MATH::INF "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::MathInf));
|
||||
|
||||
let out = test_parse!(parse_value_table, r#" MATH::NEG_INF "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" MATH::NEG_INF "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::MathNegInf));
|
||||
|
||||
let out = test_parse!(parse_value_table, r#" TIME::EPOCH "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" TIME::EPOCH "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::TimeEpoch));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn constant_mixedcase() {
|
||||
let out = test_parse!(parse_value_table, r#" MaTh::Pi "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" MaTh::Pi "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::MathPi));
|
||||
|
||||
let out = test_parse!(parse_value_table, r#" MaTh::Inf "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" MaTh::Inf "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::MathInf));
|
||||
|
||||
let out = test_parse!(parse_value_table, r#" MaTh::Neg_Inf "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" MaTh::Neg_Inf "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::MathNegInf));
|
||||
|
||||
let out = test_parse!(parse_value_table, r#" TiME::ePoCH "#).unwrap();
|
||||
let out = test_parse!(parse_value_field, r#" TiME::ePoCH "#).unwrap();
|
||||
assert_eq!(out, Value::Constant(Constant::TimeEpoch));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scientific_decimal() {
|
||||
let res = test_parse!(parse_value_table, r#" 9.7e-7dec "#).unwrap();
|
||||
let res = test_parse!(parse_value_field, r#" 9.7e-7dec "#).unwrap();
|
||||
assert!(matches!(res, Value::Number(Number::Decimal(_))));
|
||||
assert_eq!(res.to_string(), "0.00000097dec")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scientific_number() {
|
||||
let res = test_parse!(parse_value_table, r#" 9.7e-5"#).unwrap();
|
||||
let res = test_parse!(parse_value_field, r#" 9.7e-5"#).unwrap();
|
||||
assert!(matches!(res, Value::Number(Number::Float(_))));
|
||||
assert_eq!(res.to_string(), "0.000097f")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn number_method() {
|
||||
let res = test_parse!(parse_value_table, r#" 9.7e-5.sin()"#).unwrap();
|
||||
let res = test_parse!(parse_value_field, r#" 9.7e-5.sin()"#).unwrap();
|
||||
let expected = Value::Idiom(Idiom(vec![
|
||||
Part::Start(Value::Number(Number::Float(9.7e-5))),
|
||||
Part::Method("sin".to_string(), vec![]),
|
||||
]));
|
||||
assert_eq!(res, expected);
|
||||
|
||||
let res = test_parse!(parse_value_table, r#" 1.sin()"#).unwrap();
|
||||
let res = test_parse!(parse_value_field, r#" 1.sin()"#).unwrap();
|
||||
let expected = Value::Idiom(Idiom(vec![
|
||||
Part::Start(Value::Number(Number::Int(1))),
|
||||
Part::Method("sin".to_string(), vec![]),
|
||||
|
@ -234,10 +234,10 @@ fn number_method() {
|
|||
|
||||
#[test]
|
||||
fn datetime_error() {
|
||||
test_parse!(parse_value_table, r#" d"2001-01-01T01:01:01.9999999999" "#).unwrap_err();
|
||||
test_parse!(parse_value_field, r#" d"2001-01-01T01:01:01.9999999999" "#).unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_string() {
|
||||
test_parse!(parse_value_table, "").unwrap_err();
|
||||
test_parse!(parse_value_field, "").unwrap_err();
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ impl Parser<'_> {
|
|||
pub(crate) async fn parse_range(&mut self, ctx: &mut Stk) -> ParseResult<Range> {
|
||||
// Check for beginning id
|
||||
let beg = if Self::kind_is_identifier(self.peek_whitespace().kind) {
|
||||
let v = ctx.run(|ctx| self.parse_value_table(ctx)).await?;
|
||||
let v = ctx.run(|ctx| self.parse_value_inherit(ctx)).await?;
|
||||
|
||||
if self.eat_whitespace(t!(">")) {
|
||||
Bound::Excluded(v)
|
||||
|
@ -142,7 +142,7 @@ impl Parser<'_> {
|
|||
|
||||
// parse ending id.
|
||||
let end = if Self::kind_is_identifier(self.peek_whitespace().kind) {
|
||||
let v = ctx.run(|ctx| self.parse_value_table(ctx)).await?;
|
||||
let v = ctx.run(|ctx| self.parse_value_inherit(ctx)).await?;
|
||||
if inclusive {
|
||||
Bound::Included(v)
|
||||
} else {
|
||||
|
|
|
@ -69,7 +69,7 @@ impl Parse<Self> for Expression {
|
|||
let mut parser = Parser::new(val.as_bytes());
|
||||
let mut stack = Stack::new();
|
||||
let value = stack
|
||||
.enter(|ctx| parser.parse_value_table(ctx))
|
||||
.enter(|ctx| parser.parse_value_field(ctx))
|
||||
.finish()
|
||||
.map_err(|e| e.render_on(val))
|
||||
.unwrap();
|
||||
|
|
Loading…
Reference in a new issue