surrealdb-sql 1.1.0

Full type definitions for the SurrealQL query language
Documentation
use super::super::{common::commas, ending::field as ending, idiom::plain, value::value, IResult};
use crate::{syn::v1::comment::shouldbespace, Field, Fields};
use nom::{
	branch::alt,
	bytes::complete::tag_no_case,
	combinator::{cut, opt},
	multi::separated_list1,
	sequence::delimited,
};

pub fn fields(i: &str) -> IResult<&str, Fields> {
	alt((field_one, field_many))(i)
}

fn field_one(i: &str) -> IResult<&str, Fields> {
	let (i, _) = tag_no_case("VALUE")(i)?;
	let (i, _) = shouldbespace(i)?;
	cut(|i| {
		let (i, f) = alone(i)?;
		let (i, _) = ending(i)?;
		Ok((i, Fields(vec![f], true)))
	})(i)
}

pub fn field(i: &str) -> IResult<&str, Field> {
	alt((all, alone))(i)
}

fn field_many(i: &str) -> IResult<&str, Fields> {
	let (i, v) = separated_list1(commas, field)(i)?;
	Ok((i, Fields(v, false)))
}

pub fn all(i: &str) -> IResult<&str, Field> {
	let (i, _) = tag_no_case("*")(i)?;
	Ok((i, Field::All))
}

pub fn alone(i: &str) -> IResult<&str, Field> {
	let (i, expr) = value(i)?;
	let (i, alias) =
		if let (i, Some(_)) = opt(delimited(shouldbespace, tag_no_case("AS"), shouldbespace))(i)? {
			let (i, alias) = cut(plain)(i)?;
			(i, Some(alias))
		} else {
			(i, None)
		};
	Ok((
		i,
		Field::Single {
			expr,
			alias,
		},
	))
}