reifydb-rql 0.4.9

ReifyDB Query Language (RQL) parser and AST
Documentation
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2025 ReifyDB

use crate::{
	Result,
	ast::{ast::AstPatch, parse::Parser},
	error::OperationKind,
	token::keyword::Keyword,
};

impl<'bump> Parser<'bump> {
	pub(crate) fn parse_patch(&mut self) -> Result<AstPatch<'bump>> {
		let (token, assignments, rql) =
			self.parse_keyword_with_braced_expressions(Keyword::Patch, OperationKind::Patch)?;
		Ok(AstPatch {
			token,
			assignments,
			rql,
		})
	}
}

#[cfg(test)]
pub mod tests {
	use super::*;
	use crate::{ast::ast::InfixOperator, bump::Bump, token::tokenize};

	#[test]
	fn test_patch_colon_syntax() {
		let bump = Bump::new();
		let source = "PATCH {status: \"active\"}";
		let tokens = tokenize(&bump, source).unwrap().into_iter().collect();
		let mut parser = Parser::new(&bump, source, tokens);
		let mut result = parser.parse().unwrap();

		let result = result.pop().unwrap();
		let patch = result.first_unchecked().as_patch();
		assert_eq!(patch.assignments.len(), 1);

		let infix = patch.assignments[0].as_infix();
		assert!(matches!(infix.operator, InfixOperator::As(_)));
		assert_eq!(infix.right.as_identifier().text(), "status");
	}

	#[test]
	fn test_patch_multiple_assignments() {
		let bump = Bump::new();
		let source = "PATCH {status: \"active\", score: 100}";
		let tokens = tokenize(&bump, source).unwrap().into_iter().collect();
		let mut parser = Parser::new(&bump, source, tokens);
		let mut result = parser.parse().unwrap();

		let result = result.pop().unwrap();
		let patch = result.first_unchecked().as_patch();
		assert_eq!(patch.assignments.len(), 2);

		let first_infix = patch.assignments[0].as_infix();
		assert!(matches!(first_infix.operator, InfixOperator::As(_)));
		assert_eq!(first_infix.right.as_identifier().text(), "status");

		let second_infix = patch.assignments[1].as_infix();
		assert!(matches!(second_infix.operator, InfixOperator::As(_)));
		assert_eq!(second_infix.right.as_identifier().text(), "score");
	}

	#[test]
	fn test_patch_without_braces_fails() {
		let bump = Bump::new();
		let source = "PATCH 1";
		let tokens = tokenize(&bump, source).unwrap().into_iter().collect();
		let mut parser = Parser::new(&bump, source, tokens);

		let result = parser.parse().unwrap_err();
		assert_eq!(result.code, "PATCH_001");
	}
}