surrealdb-sql 1.1.0

Full type definitions for the SurrealQL query language
Documentation
use super::{
	comment::mightbespace,
	common::{closebraces, colons, expect_delimited, openbraces},
	stmt::{
		create, define, delete, foreach, ifelse, insert, output, r#break, r#continue, relate,
		remove, select, set, throw, update,
	},
	value::value,
	IResult,
};
use crate::{block::Entry, Block};
use nom::{
	branch::alt,
	combinator::map,
	multi::{many0, separated_list0},
	sequence::delimited,
};

pub fn block(i: &str) -> IResult<&str, Block> {
	expect_delimited(
		openbraces,
		|i| {
			let (i, v) = separated_list0(colons, entry)(i)?;
			let (i, _) = many0(colons)(i)?;
			Ok((i, Block(v)))
		},
		closebraces,
	)(i)
}

pub fn entry(i: &str) -> IResult<&str, Entry> {
	delimited(
		mightbespace,
		alt((
			map(set, Entry::Set),
			map(output, Entry::Output),
			map(ifelse, Entry::Ifelse),
			map(select, Entry::Select),
			map(create, Entry::Create),
			map(update, Entry::Update),
			map(relate, Entry::Relate),
			map(delete, Entry::Delete),
			map(insert, Entry::Insert),
			map(define, Entry::Define),
			map(remove, Entry::Remove),
			map(throw, Entry::Throw),
			map(r#break, Entry::Break),
			map(r#continue, Entry::Continue),
			map(foreach, Entry::Foreach),
			map(value, Entry::Value),
		)),
		mightbespace,
	)(i)
}

#[cfg(test)]
mod test {
	use super::*;

	#[test]
	fn block_empty() {
		let sql = "{}";
		let res = block(sql);
		assert!(res.is_ok());
		let out = res.unwrap().1;
		assert_eq!(sql, format!("{}", out))
	}

	#[test]
	fn block_value() {
		let sql = "{ 80 }";
		let res = block(sql);
		assert!(res.is_ok());
		let out = res.unwrap().1;
		assert_eq!(sql, format!("{}", out))
	}

	#[test]
	fn block_ifelse() {
		let sql = "{ RETURN IF true THEN 50 ELSE 40 END; }";
		let res = block(sql);
		assert!(res.is_ok());
		let out = res.unwrap().1;
		assert_eq!(sql, format!("{}", out))
	}

	#[test]
	fn block_multiple() {
		let sql = r#"{

	LET $person = (SELECT * FROM person WHERE first = $first AND last = $last AND birthday = $birthday);

	RETURN IF $person[0].id THEN
		$person[0]
	ELSE
		(CREATE person SET first = $first, last = $last, birthday = $birthday)
	END;

}"#;
		let res = block(sql);
		assert!(res.is_ok());
		let out = res.unwrap().1;
		assert_eq!(sql, format!("{:#}", out))
	}
}