Module: Amoskeag
- Defined in:
- lib/amoskeag-rb.rb,
lib/amoskeag-rb/version.rb
Overview
Amoskeag - A secure, functional DSL for business rules
The native extension defines:
- Amoskeag::Error < StandardError
- Amoskeag::CompileError < Amoskeag::Error
- Amoskeag::EvalError < Amoskeag::Error
- Amoskeag::Program (compiled program class)
- Amoskeag.compile(source, symbols = []) -> Program
- Amoskeag.evaluate(program, data) -> Object
- Amoskeag.eval_expression(source, data, symbols = []) -> Object
Defined Under Namespace
Classes: Program
Constant Summary collapse
- VERSION =
"0.2.0"- AMOSKEAG_VERSION =
"0.1.2"
Class Method Summary collapse
-
.compile(source, symbols = []) ⇒ Object
Override the compile method (no wrapping needed, just validation).
-
.compile_native ⇒ Object
Alias native methods for potential future wrapper use.
-
.eval_expression(source, data, symbols = []) ⇒ Object
Override the eval_expression method to wrap/unwrap symbols and validate data.
- .eval_expression_native ⇒ Object
-
.evaluate(program, data) ⇒ Object
Override the evaluate method to wrap/unwrap symbols and validate data.
- .evaluate_native ⇒ Object
-
.unwrap_symbols(value) ⇒ Object
Unwrap symbols from their hash representation at the top level only This allows expression results like
:adultto be returned as symbols while keeping symbols nested in data structures in wrapped format. -
.validate_data(data, path = "data") ⇒ Object
Validate that data is JSON-serializable.
-
.wrap_symbols(value) ⇒ Object
Recursively wrap symbols for native processing.
Class Method Details
.compile(source, symbols = []) ⇒ Object
Override the compile method (no wrapping needed, just validation)
100 101 102 |
# File 'lib/amoskeag-rb.rb', line 100 def self.compile(source, symbols = []) compile_native(source, symbols) end |
.compile_native ⇒ Object
Alias native methods for potential future wrapper use
37 |
# File 'lib/amoskeag-rb.rb', line 37 alias compile_native compile |
.eval_expression(source, data, symbols = []) ⇒ Object
Override the eval_expression method to wrap/unwrap symbols and validate data
112 113 114 115 116 |
# File 'lib/amoskeag-rb.rb', line 112 def self.eval_expression(source, data, symbols = []) validate_data(data) result = eval_expression_native(source, data, symbols) unwrap_symbols(result) end |
.eval_expression_native ⇒ Object
39 |
# File 'lib/amoskeag-rb.rb', line 39 alias eval_expression_native eval_expression |
.evaluate(program, data) ⇒ Object
Override the evaluate method to wrap/unwrap symbols and validate data
105 106 107 108 109 |
# File 'lib/amoskeag-rb.rb', line 105 def self.evaluate(program, data) validate_data(data) result = evaluate_native(program, data) unwrap_symbols(result) end |
.evaluate_native ⇒ Object
38 |
# File 'lib/amoskeag-rb.rb', line 38 alias evaluate_native evaluate |
.unwrap_symbols(value) ⇒ Object
Unwrap symbols from their hash representation at the top level only
This allows expression results like :adult to be returned as symbols
while keeping symbols nested in data structures in wrapped format
44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/amoskeag-rb.rb', line 44 def unwrap_symbols(value) case value when Hash # Check if this is a wrapped symbol at the top level if value.keys == ["__symbol__"] value["__symbol__"].to_sym else # Don't unwrap nested symbols - they're part of data structures value end else value end end |
.validate_data(data, path = "data") ⇒ Object
Validate that data is JSON-serializable
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/amoskeag-rb.rb', line 74 def validate_data(data, path = "data") case data when String, Integer, Float, TrueClass, FalseClass, NilClass, Symbol # These are valid types (note: not all Numeric, only Integer and Float) data when Hash data.each do |key, value| unless key.is_a?(String) || key.is_a?(Symbol) raise ArgumentError, "#{path} key must be String or Symbol, got #{key.class}" end validate_data(value, "#{path}[#{key.inspect}]") end data when Array data.each_with_index do |item, idx| validate_data(item, "#{path}[#{idx}]") end data else # Invalid type - include path information raise ArgumentError, "#{path} contains invalid type #{data.class}" end end |
.wrap_symbols(value) ⇒ Object
Recursively wrap symbols for native processing
60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/amoskeag-rb.rb', line 60 def wrap_symbols(value) case value when Symbol { "__symbol__" => value.to_s } when Hash value.transform_values { |v| wrap_symbols(v) } when Array value.map { |v| wrap_symbols(v) } else value end end |