fnordfish / teckel

Ruby operations with enforced contracts for input/output/error data structures

Home Page:https://fnordfish.github.io/teckel/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dependency injection for Operation and Chain

fnordfish opened this issue · comments

(as part of the roadmap)

Allow an Operation or Chain to take additional one-time parameters for it's execution.

Possible interface:

class MyOperation
  include ::Teckel::Operation
  
  settings Types::Hash.schema(foo: Types::String)

  def call(input)
    input == "input"
    settings[:foo] == "bar"
  end
end

MyOperation.with(foo: "bar").call("input") # call sees input == "input" && settings[:foo] == "bar"
MyOperation.call("input")  # call sees input == "input" && settings[:foo] == nil
MyOperation.with(unexpected: "bar") # depending on the `settings` class type might raise

Like input has a input_constructor, settings should have a settings_constructor as well.

Chains should be able to pass settings to a specified step:

class MyChain
  include Teckel::Chain

  step :my_step, MyOperation
end

MyChain.with(my_step: {foo: "bar"}).call(input) # invokes MyOperation.with({foo: bar}).call(input)

Is there any use case for configuring the Chain itself? How would that look like?

One use case I can see is something like:

class MyChain
  include Teckel::Chain

  step :my_step, MyOperation

  # Optional
  fails_with MyFailure
end

# Or, less bloaty as a function on the chain itself:

MyChain.with(my_step: {foo: "bar"}).call(input).or_else(->(e) { puts e })

The .or_else part already working via .success { |error| ... }
But I totally agree, that a plug-able result would be nice. Let's open a new issue for that.