Class: TypedOperation::Pipeline

Inherits:
Object
  • Object
show all
Defined in:
lib/typed_operation/pipeline.rb,
lib/typed_operation/pipeline/builder.rb,
lib/typed_operation/pipeline/step_wrapper.rb,
lib/typed_operation/pipeline/chainable_wrapper.rb,
lib/typed_operation/pipeline/empty_pipeline_chain.rb

Overview

DSL for building declarative pipelines of operations. Pipeline is syntactic sugar over the composition/chaining system. Internally builds chains, adding named steps, conditions, and error attribution.

Defined Under Namespace

Classes: Builder, ChainableWrapper, EmptyPipelineChain, StepWrapper

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(steps = [], failure_handler = nil) ⇒ Pipeline

: (?Array[Hash[Symbol, untyped]], ?(^(untyped, Symbol) -> untyped)?) -> void



28
29
30
31
32
# File 'lib/typed_operation/pipeline.rb', line 28

def initialize(steps = [], failure_handler = nil)
  @steps = steps.freeze
  @failure_handler = failure_handler
  @chain = nil
end

Instance Attribute Details

#failure_handlerObject (readonly)

: (^(untyped, Symbol) -> untyped)?



17
18
19
# File 'lib/typed_operation/pipeline.rb', line 17

def failure_handler
  @failure_handler
end

#stepsObject (readonly)

Returns the value of attribute steps.



16
17
18
# File 'lib/typed_operation/pipeline.rb', line 16

def steps
  @steps
end

Class Method Details

.build(&block) ⇒ Object

Build a new pipeline using the DSL. : () { () -> void } -> Pipeline



21
22
23
24
25
# File 'lib/typed_operation/pipeline.rb', line 21

def self.build(&block)
  builder = Builder.new
  builder.instance_eval(&block)
  new(builder.steps, builder.failure_handler)
end

Instance Method Details

#+(other) ⇒ Object

Smart composition operator. : (Pipeline | untyped) -> Pipeline



62
63
64
65
66
67
68
69
# File 'lib/typed_operation/pipeline.rb', line 62

def +(other)
  case other
  when Pipeline
    compose(other)
  else
    append(other)
  end
end

#append(operation, name: nil, if: nil) ⇒ Object

Append an operation as a new step, returning a new Pipeline. : (untyped, ?name: Symbol?, ?if: (^(untyped) -> boolish)?) -> Pipeline



42
43
44
45
46
47
48
49
50
51
# File 'lib/typed_operation/pipeline.rb', line 42

def append(operation, name: nil, if: nil)
  condition = binding.local_variable_get(:if)
  new_step = {
    type: :step,
    name: name || derive_name(operation),
    operation: operation,
    condition: condition
  }
  self.class.new(@steps + [new_step], @failure_handler)
end

#call(*args, **kwargs) ⇒ Object

Execute the pipeline by delegating to the internal chain. : (*untyped, **untyped) -> untyped



36
37
38
# File 'lib/typed_operation/pipeline.rb', line 36

def call(*args, **kwargs)
  chain.call(*args, **kwargs)
end

#compose(other, on_failure: nil) ⇒ Object

Compose with another pipeline, merging steps. : (Pipeline, ?on_failure: (:left | :right | ^(untyped, Symbol) -> untyped)?) -> Pipeline



55
56
57
58
# File 'lib/typed_operation/pipeline.rb', line 55

def compose(other, on_failure: nil)
  handler = resolve_failure_handlers(other, on_failure)
  self.class.new(@steps + other.steps, handler)
end

#to_chainObject

Convert to a bare chain for full Composition flexibility. : () -> ChainableWrapper



73
74
75
# File 'lib/typed_operation/pipeline.rb', line 73

def to_chain
  ChainableWrapper.new(self)
end