Class: Flowy::Pipeline

Inherits:
Object
  • Object
show all
Defined in:
lib/flowy/pipeline.rb

Instance Method Summary collapse

Constructor Details

#initialize(steps: []) ⇒ Pipeline

Returns a new instance of Pipeline.



23
24
25
# File 'lib/flowy/pipeline.rb', line 23

def initialize(steps: [])
  @steps = steps.freeze
end

Instance Method Details

#>>(other) ⇒ Object

Raises:

  • (TypeError)


66
67
68
69
70
# File 'lib/flowy/pipeline.rb', line 66

def >>(other)
  raise TypeError, ">> requires a Flowy::Pipeline, got #{other.class}" unless other.is_a?(Flowy::Pipeline)

  self.class.new(steps: @steps + other._raw_steps)
end

#branch(on:, &builder_block) ⇒ Object

Raises:

  • (ArgumentError)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/flowy/pipeline.rb', line 42

def branch(on:, &builder_block)
  raise ArgumentError, "branch requires a block" unless builder_block

  builder = BranchBuilder.new
  builder_block.call(builder)

  new_step = {
    type:      :branch,
    name:      :"branch(#{on.is_a?(Symbol) ? on : 'λ'})",
    on:        on,
    branches:  builder._branches.transform_values(&:call).freeze,
    otherwise: builder._otherwise&.call
  }.freeze

  self.class.new(steps: @steps + [new_step])
end

#call(starting_data: {}, rescue_errors: false, context: nil) ⇒ Object



72
73
74
75
76
77
78
79
80
# File 'lib/flowy/pipeline.rb', line 72

def call(starting_data: {}, rescue_errors: false, context: nil)
  initial = Flowy::Result.success(data: starting_data)

  @steps.reduce(initial) do |current, step_def|
    break current if current.failure?

    execute_step(step_def, current, rescue_errors: rescue_errors, context: context)
  end
end

#empty?Boolean

Returns:

  • (Boolean)


103
104
105
# File 'lib/flowy/pipeline.rb', line 103

def empty?
  @steps.empty?
end

#sizeObject



99
100
101
# File 'lib/flowy/pipeline.rb', line 99

def size
  @steps.size
end

#step(name, &callable) ⇒ Object

Two forms: block form (‘step(:name) { |prev| … }`) and symbolic form (`step(:name)` with no block, resolved against `context:` at call time).



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/flowy/pipeline.rb', line 29

def step(name, &callable)
  new_step =
    if callable
      { type: :step, name: name, callable: callable }
    elsif name.is_a?(Symbol)
      { type: :step, name: name, symbolic: true }
    else
      raise ArgumentError, "step requires a block or a Symbol name"
    end

  self.class.new(steps: @steps + [new_step.freeze])
end

#stepsObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/flowy/pipeline.rb', line 82

def steps
  @steps.map do |s|
    case s[:type]
    when :branch
      {
        type:      :branch,
        name:      s[:name],
        on:        s[:on],
        branches:  s[:branches].transform_values { |sub| sub.is_a?(Flowy::Pipeline) ? sub.steps : sub },
        otherwise: s[:otherwise].is_a?(Flowy::Pipeline) ? s[:otherwise].steps : s[:otherwise]
      }
    else
      { type: s[:type], name: s[:name] }
    end
  end
end

#tap_step(name, &callable) ⇒ Object

Raises:

  • (ArgumentError)


59
60
61
62
63
64
# File 'lib/flowy/pipeline.rb', line 59

def tap_step(name, &callable)
  raise ArgumentError, "tap_step requires a block" unless callable

  new_step = { type: :tap_step, name: name, callable: callable }.freeze
  self.class.new(steps: @steps + [new_step])
end