lib/micro/service/pipeline.rb in u-service-0.14.0 vs lib/micro/service/pipeline.rb in u-service-1.0.0

- old
+ new

@@ -1,98 +1,56 @@ # frozen_string_literal: true module Micro module Service module Pipeline - class Reducer - attr_reader :services - - InvalidServices = ArgumentError.new('argument must be a collection of `Micro::Service::Base` classes'.freeze) - - private_constant :InvalidServices - - def self.map_services(arg) - return arg.services if arg.is_a?(Reducer) - return arg.__pipeline__.services if arg.is_a?(Class) && arg < Micro::Service::Pipeline - Array(arg) - end - - def self.build(args) - services = Array(args).flat_map { |arg| map_services(arg) } - - raise InvalidServices if services.any? { |klass| !(klass < ::Micro::Service::Base) } - - new(services) - end - - def initialize(services) - @services = services - end - - def call(arg = {}) - @services.reduce(initial_result(arg)) do |result, service| - break result if result.failure? - service.__new__(result, result.value).call - end - end - - def >>(arg) - Reducer.build(services + self.class.map_services(arg)) - end - - private - - def initial_result(arg) - return arg.call if arg_to_call?(arg) - return arg if arg.is_a?(Micro::Service::Result) - result = Micro::Service::Result.new - result.__set__(true, arg, :ok, nil) - end - - def arg_to_call?(arg) - return true if arg.is_a?(Micro::Service::Base) || arg.is_a?(Reducer) - return true if arg.is_a?(Class) && (arg < Micro::Service::Base || arg < Micro::Service::Pipeline) - return false - end - end - module ClassMethods def __pipeline__ @__pipeline end def pipeline(*args) - @__pipeline = Reducer.build(args) + @__pipeline = pipeline_reducer.build(args) end def call(options = {}) new(options).call end end - private_constant :ClassMethods - - def self.[](*args) - Reducer.build(args) + CONSTRUCTOR = <<-RUBY + def initialize(options) + @options = options + pipeline = self.class.__pipeline__ + raise Error::UndefinedPipeline unless pipeline end + RUBY - UndefinedPipeline = ArgumentError.new("This class hasn't declared its pipeline. Please, use the `pipeline()` macro to define one.".freeze) + private_constant :ClassMethods, :CONSTRUCTOR - private_constant :UndefinedPipeline - def self.included(base) + def base.pipeline_reducer; Reducer; end base.extend(ClassMethods) - base.class_eval(<<-RUBY) - def initialize(options) - @options = options - pipeline = self.class.__pipeline__ - raise UndefinedPipeline unless pipeline - end - RUBY + base.class_eval(CONSTRUCTOR) end + def self.[](*args) + Reducer.build(args) + end + def call self.class.__pipeline__.call(@options) + end + + module Safe + def self.included(base) + base.send(:include, Micro::Service::Pipeline) + def base.pipeline_reducer; SafeReducer; end + end + + def self.[](*args) + SafeReducer.build(args) + end end end end end