Sha256: dab80dc8bfcf98839a6cf4c3158cd92ba4330e107642065a76b230cdcad4c005

Contents?: true

Size: 1.49 KB

Versions: 1

Compression:

Stored size: 1.49 KB

Contents

require 'lou/transformer/step'

module Lou
  module Transformer
    # never raise this...
    class NeverError < StandardError; end

    def self.extended(base)
      base.class_eval do
        self.transformer_steps = []
        self.transformer_error_class = Lou::Transformer::NeverError
      end
    end

    def revert_on(error)
      self.transformer_error_class = error
    end

    def step(transformer)
      transformer.tap do |t|
        self.transformer_steps += [t]
      end
    end

    def up(&block)
      Transformer::Step.new.up(&block)
    end

    def down(&block)
      Transformer::Step.new.down(&block)
    end

    def apply(input, total_steps = transformer_steps.count)
      applied_steps = 0
      begin
        transformer_steps.last(total_steps).each do |t|
          input = t.apply(input)
          applied_steps += 1
        end
      rescue transformer_error_class => e
        revert(input, applied_steps) if total_steps == transformer_steps.count
        raise e
      end
      input
    end

    def revert(output, total_steps = transformer_steps.count)
      reversed_steps = 0
      begin
        transformer_steps.first(total_steps).reverse_each do |t|
          output = t.revert(output)
          reversed_steps += 1
        end
      rescue transformer_error_class => e
        apply(output, reversed_steps) if total_steps == transformer_steps.count
        raise e
      end
      output
    end

    protected

    attr_accessor :transformer_steps, :transformer_error_class
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
lou-0.3.0 lib/lou/transformer.rb