Make `ASTNode` sensitive to COW style parsing

next
Sayan Nandan 2 years ago
parent e4836fd7b3
commit 25ef03221b
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -523,9 +523,9 @@ pub enum Statement<'a> {
/// DDL query to switch between spaces and models
Use(Entity<'a>),
/// DDL query to create a model
CreateModel(ddl::crt::Model<'a>),
CreateModel(ddl::crt::CreateModel<'a>),
/// DDL query to create a space
CreateSpace(ddl::crt::Space<'a>),
CreateSpace(ddl::crt::CreateSpace<'a>),
/// DDL query to alter a space (properties)
AlterSpace(ddl::alt::AlterSpace<'a>),
/// DDL query to alter a model (properties, field types, etc)

@ -28,12 +28,49 @@
use crate::engine::ql::{ast::InplaceData, lex::Token};
use crate::engine::ql::{
ast::{QueryData, State},
LangResult,
LangError, LangResult,
};
/// An AST node
pub trait ASTNode<'a>: Sized {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self>;
const VERIFY: bool = false;
/// Parse this AST node from the given state
///
/// Note to implementors:
/// - If the implementor uses a cow style parse, then set [`ASTNode::VERIFY`] to
/// true
/// - Try to propagate errors via [`State`] if possible
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self>;
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let r = <Self as ASTNode>::_from_state(state);
if Self::VERIFY {
return if state.okay() {
r
} else {
Err(LangError::UnexpectedToken)
};
}
r
}
#[cfg(test)]
/// Parse multiple nodes of this AST node type. Intended for the test suite.
fn _multiple_from_state<Qd: QueryData<'a>>(_: &mut State<'a, Qd>) -> LangResult<Vec<Self>> {
unimplemented!()
}
#[cfg(test)]
fn multiple_from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Vec<Self>> {
let r = <Self as ASTNode>::_multiple_from_state(state);
if Self::VERIFY {
return if state.okay() {
r
} else {
Err(LangError::UnexpectedToken)
};
}
r
}
#[cfg(test)]
/// Parse this AST node utilizing the full token-stream. Intended for the test suite.
fn from_insecure_tokens_full(tok: &'a [Token<'a>]) -> LangResult<Self> {
let mut state = State::new(tok, InplaceData::new());
let r = <Self as ASTNode>::from_state(&mut state)?;
@ -41,10 +78,8 @@ pub trait ASTNode<'a>: Sized {
Ok(r)
}
#[cfg(test)]
fn multiple_from_state<Qd: QueryData<'a>>(_: &mut State<'a, Qd>) -> LangResult<Vec<Self>> {
unimplemented!()
}
#[cfg(test)]
/// Parse multiple nodes of this AST node type, utilizing the full token stream.
/// Intended for the test suite.
fn multiple_from_insecure_tokens_full(tok: &'a [Token<'a>]) -> LangResult<Vec<Self>> {
let mut state = State::new(tok, InplaceData::new());
let r = Self::multiple_from_state(&mut state);

@ -183,12 +183,12 @@ mod impls {
LangResult,
};
impl<'a> ASTNode<'a> for AlterModel<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse(state)
}
}
impl<'a> ASTNode<'a> for AlterSpace<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse(state)
}
}

@ -36,14 +36,14 @@ use crate::{
#[derive(Debug, PartialEq)]
/// A space
pub struct Space<'a> {
pub struct CreateSpace<'a> {
/// the space name
pub(super) space_name: Slice<'a>,
/// properties
pub(super) props: Dict,
}
impl<'a> Space<'a> {
impl<'a> CreateSpace<'a> {
#[inline(always)]
/// Parse space data from the given tokens
fn parse<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
@ -63,7 +63,7 @@ impl<'a> Space<'a> {
syn::rfold_dict(DictFoldState::OB, state, &mut d);
}
if state.okay() {
Ok(Space {
Ok(CreateSpace {
space_name: unsafe { extract!(space_name, Token::Ident(ref id) => id.clone()) },
props: d,
})
@ -75,7 +75,7 @@ impl<'a> Space<'a> {
#[derive(Debug, PartialEq)]
/// A model definition
pub struct Model<'a> {
pub struct CreateModel<'a> {
/// the model name
model_name: Slice<'a>,
/// the fields
@ -91,7 +91,7 @@ pub struct Model<'a> {
)
*/
impl<'a> Model<'a> {
impl<'a> CreateModel<'a> {
pub fn new(model_name: Slice<'a>, fields: Vec<Field<'a>>, props: Dict) -> Self {
Self {
model_name,
@ -142,18 +142,18 @@ impl<'a> Model<'a> {
}
mod impls {
use super::{Model, Space};
use super::{CreateModel, CreateSpace};
use crate::engine::ql::{
ast::{traits::ASTNode, QueryData, State},
LangResult,
};
impl<'a> ASTNode<'a> for Space<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
impl<'a> ASTNode<'a> for CreateSpace<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse(state)
}
}
impl<'a> ASTNode<'a> for Model<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
impl<'a> ASTNode<'a> for CreateModel<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse(state)
}
}

@ -107,19 +107,19 @@ mod impls {
LangResult,
};
impl<'a> ASTNode<'a> for DropModel<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse(state)
}
}
impl<'a> ASTNode<'a> for DropSpace<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse(state)
}
}
#[derive(sky_macros::Wrapper, Debug)]
pub struct DropStatementAST<'a>(Statement<'a>);
impl<'a> ASTNode<'a> for DropStatementAST<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
super::parse_drop(state).map(Self)
}
}

@ -72,7 +72,7 @@ mod impls {
#[derive(sky_macros::Wrapper, Debug)]
pub struct InspectStatementAST<'a>(Statement<'a>);
impl<'a> ASTNode<'a> for InspectStatementAST<'a> {
fn from_state<Qd: QueryData<'a>>(
fn _from_state<Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> crate::engine::ql::LangResult<Self> {
super::parse_inspect(state).map(Self)

@ -505,78 +505,70 @@ mod impls {
};
use crate::engine::ql::{
ast::{traits::ASTNode, QueryData, State},
LangError, LangResult,
LangResult,
};
impl<'a> ASTNode<'a> for ExpandedField<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse(state)
}
fn multiple_from_state<Qd: QueryData<'a>>(
fn _multiple_from_state<Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> LangResult<Vec<Self>> {
Self::parse_multiple(state).map(Vec::from)
}
}
impl<'a> ASTNode<'a> for Layer<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let mut layers = Vec::new();
rfold_layers(LayerFoldState::BEGIN_IDENT, state, &mut layers);
assert!(layers.len() == 1);
Ok(layers.swap_remove(0))
}
fn multiple_from_state<Qd: QueryData<'a>>(
fn _multiple_from_state<Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> LangResult<Vec<Self>> {
let mut l = Vec::new();
rfold_layers(LayerFoldState::BEGIN_IDENT, state, &mut l);
if state.okay() {
Ok(l)
} else {
Err(LangError::UnexpectedToken)
}
Ok(l)
}
}
#[derive(sky_macros::Wrapper, Debug)]
pub struct DictBasic(Dict);
impl<'a> ASTNode<'a> for DictBasic {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let mut dict = Dict::new();
rfold_dict(DictFoldState::OB, state, &mut dict);
if state.okay() {
Ok(Self(dict))
} else {
Err(LangError::UnexpectedToken)
}
Ok(Self(dict))
}
}
#[derive(sky_macros::Wrapper, Debug)]
pub struct DictTypeMetaSplit(Dict);
impl<'a> ASTNode<'a> for DictTypeMetaSplit {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let mut dict = Dict::new();
rfold_tymeta(DictFoldState::CB_OR_IDENT, state, &mut dict);
if state.okay() {
Ok(Self(dict))
} else {
Err(LangError::UnexpectedToken)
}
Ok(Self(dict))
}
}
#[derive(sky_macros::Wrapper, Debug)]
pub struct DictTypeMeta(Dict);
impl<'a> ASTNode<'a> for DictTypeMeta {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let mut dict = Dict::new();
rfold_tymeta(DictFoldState::OB, state, &mut dict);
if state.okay() {
Ok(Self(dict))
} else {
Err(LangError::UnexpectedToken)
}
Ok(Self(dict))
}
}
impl<'a> ASTNode<'a> for Field<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse(state)
}
}

@ -30,7 +30,7 @@ use {
super::WhereClause,
crate::{
engine::ql::{
ast::{traits::ASTNode, Entity, QueryData, State},
ast::{Entity, QueryData, State},
LangError, LangResult,
},
util::{compiler, MaybeInit},
@ -94,8 +94,15 @@ impl<'a> DeleteStatement<'a> {
}
}
impl<'a> ASTNode<'a> for DeleteStatement<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse_delete(state)
mod impls {
use super::DeleteStatement;
use crate::engine::ql::{
ast::{traits::ASTNode, QueryData, State},
LangResult,
};
impl<'a> ASTNode<'a> for DeleteStatement<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse_delete(state)
}
}
}

@ -30,7 +30,7 @@ use {
engine::{
core::DataType,
ql::{
ast::{traits::ASTNode, Entity, QueryData, State},
ast::{Entity, QueryData, State},
lex::Token,
LangError, LangResult,
},
@ -207,22 +207,6 @@ unsafe fn handle_func_sub<'a, Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> O
ldfunc(func).map(move |f| f())
}
#[cfg(test)]
#[derive(sky_macros::Wrapper, Debug)]
pub struct List(Vec<DataType>);
#[cfg(test)]
impl<'a> ASTNode<'a> for List {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let mut l = Vec::new();
parse_list(state, &mut l);
if state.okay() {
Ok(List(l))
} else {
Err(LangError::UnexpectedToken)
}
}
}
/// ## Panics
/// - If tt is empty
pub(super) fn parse_data_tuple_syntax<'a, Qd: QueryData<'a>>(
@ -270,21 +254,6 @@ pub(super) fn parse_data_tuple_syntax<'a, Qd: QueryData<'a>>(
data
}
#[cfg(test)]
#[derive(sky_macros::Wrapper, Debug)]
pub struct DataTuple(Vec<Option<DataType>>);
#[cfg(test)]
impl<'a> ASTNode<'a> for DataTuple {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let r = parse_data_tuple_syntax(state);
if state.okay() {
Ok(Self(r))
} else {
Err(LangError::UnexpectedToken)
}
}
}
/// ## Panics
/// Panics if tt is empty
pub(super) fn parse_data_map_syntax<'a, Qd: QueryData<'a>>(
@ -341,30 +310,6 @@ pub(super) fn parse_data_map_syntax<'a, Qd: QueryData<'a>>(
data
}
#[cfg(test)]
#[derive(sky_macros::Wrapper, Debug)]
pub struct DataMap(HashMap<Box<str>, Option<DataType>>);
#[cfg(test)]
impl<'a> ASTNode<'a> for DataMap {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let r = parse_data_map_syntax(state);
if state.okay() {
Ok(Self(
r.into_iter()
.map(|(ident, val)| {
(
String::from_utf8_lossy(ident).to_string().into_boxed_str(),
val,
)
})
.collect(),
))
} else {
Err(LangError::UnexpectedToken)
}
}
}
#[derive(Debug, PartialEq)]
pub enum InsertData<'a> {
Ordered(Vec<Option<DataType>>),
@ -444,8 +389,67 @@ impl<'a> InsertStatement<'a> {
}
}
impl<'a> ASTNode<'a> for InsertStatement<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse_insert(state)
#[cfg(test)]
pub use impls::test::{DataMap, DataTuple, List};
mod impls {
use super::InsertStatement;
use crate::engine::ql::{
ast::{traits::ASTNode, QueryData, State},
LangResult,
};
impl<'a> ASTNode<'a> for InsertStatement<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse_insert(state)
}
}
#[cfg(test)]
pub mod test {
use super::super::{
parse_data_map_syntax, parse_data_tuple_syntax, parse_list, DataType, HashMap,
};
use crate::engine::ql::{
ast::{traits::ASTNode, QueryData, State},
LangResult,
};
#[derive(sky_macros::Wrapper, Debug)]
pub struct List(Vec<DataType>);
impl<'a> ASTNode<'a> for List {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let mut l = Vec::new();
parse_list(state, &mut l);
Ok(List(l))
}
}
#[derive(sky_macros::Wrapper, Debug)]
pub struct DataTuple(Vec<Option<DataType>>);
impl<'a> ASTNode<'a> for DataTuple {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let r = parse_data_tuple_syntax(state);
Ok(Self(r))
}
}
#[derive(sky_macros::Wrapper, Debug)]
pub struct DataMap(HashMap<Box<str>, Option<DataType>>);
impl<'a> ASTNode<'a> for DataMap {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let r = parse_data_map_syntax(state);
Ok(Self(
r.into_iter()
.map(|(ident, val)| {
(
String::from_utf8_lossy(ident).to_string().into_boxed_str(),
val,
)
})
.collect(),
))
}
}
}
}

@ -36,9 +36,8 @@ pub mod upd;
use {
super::{
ast::{traits::ASTNode, QueryData, State},
ast::{QueryData, State},
lex::{LitIR, Token},
LangError, LangResult,
},
crate::util::compiler,
std::collections::HashMap,
@ -119,12 +118,6 @@ impl<'a> RelationalExpr<'a> {
}
}
impl<'a> ASTNode<'a> for RelationalExpr<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::try_parse(state).ok_or(LangError::UnexpectedToken)
}
}
#[derive(Debug, PartialEq)]
pub struct WhereClause<'a> {
c: WhereClauseCollection<'a>,
@ -164,13 +157,26 @@ impl<'a> WhereClause<'a> {
}
}
impl<'a> ASTNode<'a> for WhereClause<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let wh = Self::parse_where(state);
if state.okay() {
#[cfg(test)]
mod impls {
use super::{
super::{
ast::{traits::ASTNode, QueryData, State},
LangError, LangResult,
},
RelationalExpr, WhereClause,
};
impl<'a> ASTNode<'a> for WhereClause<'a> {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let wh = Self::parse_where(state);
Ok(wh)
} else {
Err(LangError::UnexpectedToken)
}
}
impl<'a> ASTNode<'a> for RelationalExpr<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::try_parse(state).ok_or(LangError::UnexpectedToken)
}
}
}

@ -28,7 +28,7 @@ use {
super::{WhereClause, WhereClauseCollection},
crate::{
engine::ql::{
ast::{traits::ASTNode, Entity, QueryData, State},
ast::{Entity, QueryData, State},
lex::Token,
LangError, LangResult,
},
@ -134,8 +134,15 @@ impl<'a> SelectStatement<'a> {
}
}
impl<'a> ASTNode<'a> for SelectStatement<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse_select(state)
mod impls {
use super::SelectStatement;
use crate::engine::ql::{
ast::{traits::ASTNode, QueryData, State},
LangResult,
};
impl<'a> ASTNode<'a> for SelectStatement<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse_select(state)
}
}
}

@ -25,15 +25,12 @@
*/
#[cfg(test)]
use {
super::WhereClauseCollection,
crate::engine::ql::{ast::InplaceData, lex::Token},
};
use super::WhereClauseCollection;
use {
super::{read_ident, u, WhereClause},
crate::{
engine::ql::{
ast::{traits::ASTNode, Entity, QueryData, State},
ast::{Entity, QueryData, State},
lex::LitIR,
LangError, LangResult,
},
@ -132,20 +129,6 @@ impl<'a> AssignmentExpression<'a> {
}
}
#[cfg(test)]
pub fn parse_assn_expression_full<'a>(tok: &'a [Token]) -> Option<AssignmentExpression<'a>> {
let mut state = State::new(tok, InplaceData::new());
let mut exprs = Vec::new();
AssignmentExpression::parse_and_append_expression(&mut state, &mut exprs);
assert_full_tt!(state);
if state.okay() {
assert_eq!(exprs.len(), 1, "expected one expression, found multiple");
Some(exprs.remove(0))
} else {
None
}
}
#[derive(Debug, PartialEq)]
pub struct UpdateStatement<'a> {
pub(super) entity: Entity<'a>,
@ -227,8 +210,36 @@ impl<'a> UpdateStatement<'a> {
}
}
impl<'a> ASTNode<'a> for UpdateStatement<'a> {
fn from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse_update(state)
mod impls {
use super::UpdateStatement;
use crate::engine::ql::{
ast::{traits::ASTNode, QueryData, State},
LangResult,
};
impl<'a> ASTNode<'a> for UpdateStatement<'a> {
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
Self::parse_update(state)
}
}
#[cfg(test)]
mod test {
use super::{super::AssignmentExpression, *};
impl<'a> ASTNode<'a> for AssignmentExpression<'a> {
// important: upstream must verify this
const VERIFY: bool = true;
fn _from_state<Qd: QueryData<'a>>(state: &mut State<'a, Qd>) -> LangResult<Self> {
let mut expr = Vec::new();
AssignmentExpression::parse_and_append_expression(state, &mut expr);
state.poison_if_not(expr.len() == 1);
Ok(expr.remove(0))
}
fn _multiple_from_state<Qd: QueryData<'a>>(
state: &mut State<'a, Qd>,
) -> LangResult<Vec<Self>> {
let mut expr = Vec::new();
AssignmentExpression::parse_and_append_expression(state, &mut expr);
Ok(expr)
}
}
}
}

@ -24,21 +24,6 @@
*
*/
#[cfg(test)]
macro_rules! assert_full_tt {
($a:expr, $b:expr) => {
assert_eq!($a, $b, "full token stream not utilized")
};
($a:expr) => {
assert!(
crate::engine::ql::ast::State::exhausted(&$a),
"full tt not utilized at: {}:{}",
::core::file!(),
::core::line!()
)
};
}
macro_rules! __sym_token {
($ident:ident) => {
$crate::engine::ql::lex::Token::Symbol($crate::engine::ql::lex::Symbol::$ident)

@ -690,17 +690,15 @@ mod expression_tests {
use {
super::*,
crate::engine::ql::{
dml::{
self,
upd::{AssignmentExpression, Operator},
},
ast::parse_ast_node_full,
dml::upd::{AssignmentExpression, Operator},
lex::LitIR,
},
};
#[test]
fn expr_assign() {
let src = lex_insecure(b"username = 'sayan'").unwrap();
let r = dml::upd::parse_assn_expression_full(&src).unwrap();
let r = parse_ast_node_full::<AssignmentExpression>(&src).unwrap();
assert_eq!(
r,
AssignmentExpression::new(b"username", LitIR::Str("sayan"), Operator::Assign)
@ -709,7 +707,7 @@ mod expression_tests {
#[test]
fn expr_add_assign() {
let src = lex_insecure(b"followers += 100").unwrap();
let r = dml::upd::parse_assn_expression_full(&src).unwrap();
let r = parse_ast_node_full::<AssignmentExpression>(&src).unwrap();
assert_eq!(
r,
AssignmentExpression::new(b"followers", LitIR::UInt(100), Operator::AddAssign)
@ -718,7 +716,7 @@ mod expression_tests {
#[test]
fn expr_sub_assign() {
let src = lex_insecure(b"following -= 150").unwrap();
let r = dml::upd::parse_assn_expression_full(&src).unwrap();
let r = parse_ast_node_full::<AssignmentExpression>(&src).unwrap();
assert_eq!(
r,
AssignmentExpression::new(b"following", LitIR::UInt(150), Operator::SubAssign)
@ -727,7 +725,7 @@ mod expression_tests {
#[test]
fn expr_mul_assign() {
let src = lex_insecure(b"product_qty *= 2").unwrap();
let r = dml::upd::parse_assn_expression_full(&src).unwrap();
let r = parse_ast_node_full::<AssignmentExpression>(&src).unwrap();
assert_eq!(
r,
AssignmentExpression::new(b"product_qty", LitIR::UInt(2), Operator::MulAssign)
@ -736,7 +734,7 @@ mod expression_tests {
#[test]
fn expr_div_assign() {
let src = lex_insecure(b"image_crop_factor /= 2").unwrap();
let r = dml::upd::parse_assn_expression_full(&src).unwrap();
let r = parse_ast_node_full::<AssignmentExpression>(&src).unwrap();
assert_eq!(
r,
AssignmentExpression::new(b"image_crop_factor", LitIR::UInt(2), Operator::DivAssign)

@ -408,7 +408,7 @@ mod schemas {
use crate::engine::ql::{
ast::parse_ast_node_full,
ddl::{
crt::Model,
crt::CreateModel,
syn::{Field, Layer},
},
};
@ -426,11 +426,11 @@ mod schemas {
let tok = &tok[2..];
// parse model
let model = parse_ast_node_full::<Model>(tok).unwrap();
let model = parse_ast_node_full::<CreateModel>(tok).unwrap();
assert_eq!(
model,
Model::new(
CreateModel::new(
b"mymodel",
vec![
Field::new(
@ -465,11 +465,11 @@ mod schemas {
let tok = &tok[2..];
// parse model
let model = parse_ast_node_full::<Model>(tok).unwrap();
let model = parse_ast_node_full::<CreateModel>(tok).unwrap();
assert_eq!(
model,
Model::new(
CreateModel::new(
b"mymodel",
vec![
Field::new(
@ -515,11 +515,11 @@ mod schemas {
let tok = &tok[2..];
// parse model
let model = parse_ast_node_full::<Model>(tok).unwrap();
let model = parse_ast_node_full::<CreateModel>(tok).unwrap();
assert_eq!(
model,
Model::new(
CreateModel::new(
b"mymodel",
vec![
Field::new(
@ -584,11 +584,11 @@ mod schemas {
let tok = &tok[2..];
// parse model
let model = parse_ast_node_full::<Model>(tok).unwrap();
let model = parse_ast_node_full::<CreateModel>(tok).unwrap();
assert_eq!(
model,
Model::new(
CreateModel::new(
b"mymodel",
vec![
Field::new(

Loading…
Cancel
Save