dry-rb / dry-logic

Predicate logic with rule composition
https://dry-rb.org/gems/dry-logic/
MIT License
179 stars 66 forks source link

Implement parsing string representations back to AST. #83

Closed estum closed 1 year ago

estum commented 3 years ago

RuleInterpreter takes string representations of rules, predicates or operations and parses them back to AST, which can be compiled to a rule object. So, it makes an ability to store rules as a plain text, for example in db columns, and run them as usual.

interpreter = Dry::Logic::RuleInterpreter.new(Dry::Logic::Predicates)
rule = "key?(:email)"

interpreter.(rule) 
# => [[:predicate, [:key?, [[:name, :email], [:input, Undefined]]]]]

interpreter.compile(rule)
# => #<Dry::Logic::Rule::Predicate::Predicate2Arity1Curried predicate=#<Method: Dry::Logic::Predicates.key?> options={:args=>[:user], :arity=>2}>

interpreter.compile(rule)[0].to_s == rule
# => true

To implement that feature, I have had to override Dry::Logic::Operations::Check#to_s method to hold required args.

The name of the class may be controversial, I will rename it if you've got a better one.

flash-gordon commented 3 years ago

@estum could you start a discussion at our forum per the guildelines? The problem with submitting large PRs is that in order for them to get merged we need to be on board with the idea :) Even though serialization/deserialization facilities are a good thing I would strongly argue about the format and limitations. For instance, using JSON-compatible types for dumping AST would be superior IMO. And even then something like lambdas or arbitrary objects cannot be serialized to strings or JSON, users must be properly warned about this.