From d7624311f60df5c262ed0cd5bd273e1f2362b2c7 Mon Sep 17 00:00:00 2001 From: stefan-gorules <127550877+stefan-gorules@users.noreply.github.com> Date: Sat, 15 Feb 2025 21:46:55 +0100 Subject: [PATCH] fix: py validate methods (#316) * fix: py validate methods * fix --- bindings/python/Cargo.toml | 1 - bindings/python/src/expression.rs | 29 +++------ bindings/python/src/lib.rs | 6 +- bindings/python/zen.pyi | 3 +- core/expression/src/validate.rs | 101 +++--------------------------- 5 files changed, 22 insertions(+), 118 deletions(-) diff --git a/bindings/python/Cargo.toml b/bindings/python/Cargo.toml index e38b44a8..b09e865d 100644 --- a/bindings/python/Cargo.toml +++ b/bindings/python/Cargo.toml @@ -11,7 +11,6 @@ crate-type = ["cdylib"] [dependencies] anyhow = { workspace = true } -bumpalo = "3" either = "1.13" pyo3 = { version = "0.23", features = ["anyhow", "serde", "either"] } pyo3-async-runtimes = { version = "0.23", features = ["tokio-runtime", "attributes"] } diff --git a/bindings/python/src/expression.rs b/bindings/python/src/expression.rs index 2d32d013..2cd3b31a 100644 --- a/bindings/python/src/expression.rs +++ b/bindings/python/src/expression.rs @@ -1,11 +1,10 @@ use crate::variable::PyVariable; use anyhow::{anyhow, Context}; use either::Either; -use pyo3::types::{PyAnyMethods, PyDict}; +use pyo3::types::PyDict; use pyo3::{pyclass, pyfunction, pymethods, Bound, IntoPyObjectExt, Py, PyAny, PyResult, Python}; -use pythonize::depythonize; +use pythonize::{depythonize, pythonize}; use zen_expression::expression::{Standard, Unary}; -use zen_expression::validate::{validate_expression, validate_unary_expression, ValidationError}; use zen_expression::{Expression, Variable}; #[pyfunction] @@ -100,29 +99,19 @@ impl PyExpression { } #[pyfunction] -#[pyo3(name = "validate_expression")] -pub fn py_validate_expression(py: Python, expression: String) -> PyResult>> { - let Some(err) = validate_expression(expression.as_str()) else { +pub fn validate_expression(py: Python, expression: String) -> PyResult>> { + let Err(error) = zen_expression::validate::validate_expression(expression.as_str()) else { return Ok(None); }; - return Ok(Some(convert_error_to_dict(py, &err))); + + Ok(Some(pythonize(py, &error)?.unbind())) } #[pyfunction] -#[pyo3(name = "validate_unary_expression")] -pub fn py_validate_unary_expression( - py: Python, - expression: String, -) -> PyResult>> { - let Some(err) = validate_unary_expression(expression.as_str()) else { +pub fn validate_unary_expression(py: Python, expression: String) -> PyResult>> { + let Err(error) = zen_expression::validate::validate_expression(expression.as_str()) else { return Ok(None); }; - return Ok(Some(convert_error_to_dict(py, &err))); -} -fn convert_error_to_dict(py: Python, err: &ValidationError) -> Py { - let dict = PyDict::new(py); - dict.set_item("type", &err.error_type).unwrap(); - dict.set_item("source", &err.source).unwrap(); - return dict.unbind(); + Ok(Some(pythonize(py, &error)?.unbind())) } diff --git a/bindings/python/src/lib.rs b/bindings/python/src/lib.rs index b2b2cd16..2895ec21 100644 --- a/bindings/python/src/lib.rs +++ b/bindings/python/src/lib.rs @@ -2,7 +2,7 @@ use crate::decision::PyZenDecision; use crate::engine::PyZenEngine; use crate::expression::{ compile_expression, compile_unary_expression, evaluate_expression, evaluate_unary_expression, - py_validate_expression, py_validate_unary_expression, render_template, PyExpression, + render_template, validate_expression, validate_unary_expression, PyExpression, }; use pyo3::prelude::PyModuleMethods; use pyo3::types::PyModule; @@ -28,8 +28,8 @@ fn zen(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(render_template, m)?)?; m.add_function(wrap_pyfunction!(compile_expression, m)?)?; m.add_function(wrap_pyfunction!(compile_unary_expression, m)?)?; - m.add_function(wrap_pyfunction!(py_validate_expression, m)?)?; - m.add_function(wrap_pyfunction!(py_validate_unary_expression, m)?)?; + m.add_function(wrap_pyfunction!(validate_expression, m)?)?; + m.add_function(wrap_pyfunction!(validate_unary_expression, m)?)?; Ok(()) } diff --git a/bindings/python/zen.pyi b/bindings/python/zen.pyi index b2a77ff7..0d5e3a04 100644 --- a/bindings/python/zen.pyi +++ b/bindings/python/zen.pyi @@ -54,6 +54,5 @@ def validate_unary_expression(expression: str) -> Optional[ValidationResponse]: class ValidationResponse(TypedDict): - type: Literal["lexerError","parserError", "compilerError"] + type: Literal["lexerError", "parserError", "compilerError"] source: str - diff --git a/core/expression/src/validate.rs b/core/expression/src/validate.rs index b2341f89..13d5bb0a 100644 --- a/core/expression/src/validate.rs +++ b/core/expression/src/validate.rs @@ -1,98 +1,15 @@ -use bumpalo::Bump; +use crate::{Isolate, IsolateError}; -use crate::{compiler::Compiler, lexer::Lexer, parser::Parser}; +pub fn validate_unary_expression(expression: &str) -> Result<(), IsolateError> { + let mut isolate = Isolate::new(); + isolate.compile_unary(expression)?; -pub struct ValidationError { - pub error_type: String, - pub source: String, + Ok(()) } -pub fn validate_unary_expression(expression: &str) -> Option { - let mut lexer = Lexer::new(); - let tokens = match lexer.tokenize(expression) { - Err(e) => { - return Some(ValidationError { - error_type: "lexerError".to_string(), - source: e.to_string(), - }) - } - Ok(tokens) => tokens, - }; +pub fn validate_expression(expression: &str) -> Result<(), IsolateError> { + let mut isolate = Isolate::new(); + isolate.compile_standard(expression)?; - let bump = Bump::new(); - let parser = match Parser::try_new(tokens, &bump) { - Err(e) => { - return Some(ValidationError { - error_type: "parserError".to_string(), - source: e.to_string(), - }) - } - Ok(p) => p.unary(), - }; - - let parser_result = parser.parse(); - match parser_result.error() { - Err(e) => { - return Some(ValidationError { - error_type: "parserError".to_string(), - source: e.to_string(), - }) - } - Ok(n) => n, - }; - - let mut compiler = Compiler::new(); - if let Err(e) = compiler.compile(parser_result.root) { - return Some(ValidationError { - error_type: "compilerError".to_string(), - source: e.to_string(), - }); - } - - None -} - -pub fn validate_expression(expression: &str) -> Option { - let mut lexer = Lexer::new(); - let tokens = match lexer.tokenize(expression) { - Err(e) => { - return Some(ValidationError { - error_type: "lexerError".to_string(), - source: e.to_string(), - }) - } - Ok(tokens) => tokens, - }; - - let bump = Bump::new(); - let parser = match Parser::try_new(tokens, &bump) { - Err(e) => { - return Some(ValidationError { - error_type: "parserError".to_string(), - source: e.to_string(), - }) - } - Ok(p) => p.standard(), - }; - - let parser_result = parser.parse(); - match parser_result.error() { - Err(e) => { - return Some(ValidationError { - error_type: "parserError".to_string(), - source: e.to_string(), - }) - } - Ok(n) => n, - }; - - let mut compiler = Compiler::new(); - if let Err(e) = compiler.compile(parser_result.root) { - return Some(ValidationError { - error_type: "compilerError".to_string(), - source: e.to_string(), - }); - } - - None + Ok(()) }