All Files
    (
      
  100.0%
     
     covered at
     
       
         3.84
       
     hits/line
    )
  
  
  
    20 files in total.
  
  
    203 relevant lines,
    203 lines covered and
    0 lines missed. 
    (
  100.0%
)
  
  
    
      18 total branches, 
      18 branches covered and
      0 branches missed.
      (
  100.0%
)
    
  
  
 
        
       
      
      
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
require "zeitwerk"
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
Zeitwerk::Loader.new.then do |loader|
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  loader.tag = File.basename __FILE__, ".rb"
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  loader.push_dir __dir__
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  loader.setup
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
            
              
            
            
# Main namespace.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  def self.[](container) = Builder.new(container)
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  def self.included(descendant) = descendant.include Builder.new
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  def self.loader registry = Zeitwerk::Registry
           
        
      
        
          
- 
            
              10
            
            
              
            
            
    @loader ||= registry.loaders.each.find { |loader| loader.tag == File.basename(__FILE__, ".rb") }
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
require "dry/monads"
           
        
      
        
          
- 
            
              1
            
            
              
            
            
require "refinements/array"
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
            
              
            
            
  # Defines the pipe and and associated step methods for an object.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  class Builder < Module
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    include Dry::Monads[:result]
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    using Refinements::Array
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    def initialize container = Steps::Container, pipe: Pipe
           
        
      
        
          
- 
            
              7
            
            
              
            
            
      super()
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              7
            
            
              
            
            
      @container = container
           
        
      
        
          
- 
            
              7
            
            
              
            
            
      @pipe = pipe
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              7
            
            
              
            
            
      define_pipe
           
        
      
        
          
- 
            
              7
            
            
              
            
            
      define_steps
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              7
            
            
              
            
            
      freeze
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    private
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    attr_reader :container, :pipe
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    def define_pipe pipeline = pipe
           
        
      
        
          
- 
            
              7
            
            
              
            
            
      define_method :pipe do |input, *steps|
           
        
      
        
          
- 
            
              11
            
            
              
                
                  then: 2
                
              
                
                  else: 5
                
              
            
            
        steps.each { |step| steps.supplant step, method(step) if step.is_a? Symbol }
           
        
      
        
          
- 
            
              4
            
            
              
            
            
        pipeline.call(input, *steps)
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    def define_steps vessel = container
           
        
      
        
          
- 
            
              7
            
            
              
            
            
      vessel.each_key do |key|
           
        
      
        
          
- 
            
              72
            
            
              
            
            
        define_method key do |*positionals, **keywords, &block|
           
        
      
        
          
- 
            
              3
            
            
              
            
            
          step = vessel[key]
           
        
      
        
          
- 
            
              3
            
            
              
                
                  then: 1
                
              
                
                  else: 2
                
              
            
            
          step.is_a?(Proc) ? step : step.new(*positionals, **keywords, &block)
           
        
      
        
          
- 
            
            
              
            
            
        end
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
            
              
            
            
  # Allows objects to be functionally composable.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Composable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    def >>(other) = method(:call) >> other
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    def <<(other) = method(:call) << other
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    def call = fail NoMethodError, "`#{self.class.name}##{__method__}` must be implemented."
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
require "dry/monads"
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
            
              
            
            
  # Provids low-level functionality processing a sequence of steps.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  Pipe = lambda do |input, *steps|
           
        
      
        
          
- 
            
              12
            
            
              
                
                  then: 1
                
              
                
                  else: 11
                
              
            
            
    fail ArgumentError, "Pipe must have at least one step." if steps.empty?
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              11
            
            
              
                
                  then: 2
                
              
                
                  else: 9
                
              
            
            
    result = input.is_a?(Dry::Monads::Result) ? input : Dry::Monads::Success(input)
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              11
            
            
              
            
            
    steps.reduce(&:>>).call result
           
        
      
        
          
- 
            
            
              
            
            
  rescue NoMethodError
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    raise TypeError, "Step must be functionally composable and answer a monad."
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
require "dry/monads"
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Provides a custom step blueprint.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Abstract
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      include Dry::Monads[:result]
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      include Composable
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def initialize *positionals, **keywords, &block
           
        
      
        
          
- 
            
              67
            
            
              
            
            
        @base_positionals = positionals
           
        
      
        
          
- 
            
              67
            
            
              
            
            
        @base_keywords = keywords
           
        
      
        
          
- 
            
              67
            
            
              
            
            
        @base_block = block
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      protected
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      attr_reader :base_positionals, :base_keywords, :base_block
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Wraps Dry Monads `#alt_map` method as a step.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Amap < Abstract
           
        
      
        
          
- 
            
              2
            
            
              
            
            
      def call(result) = result.alt_map { |object| base_block.call object }
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Messages object, with optional arguments, as different result.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class As < Abstract
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def call result
           
        
      
        
          
- 
            
              7
            
            
              
            
            
        result.fmap { |object| object.public_send(*base_positionals, **base_keywords) }
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Wraps Dry Monads `#bind` method as a step.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Bind < Abstract
           
        
      
        
          
- 
            
              3
            
            
              
            
            
      def call(result) = result.bind { |object| base_block.call object }
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
require "marameters"
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Checks if proof is true and answers success (passthrough) or failure (with optional argument).
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Check < Abstract
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def initialize proof, message
           
        
      
        
          
- 
            
              3
            
            
              
            
            
        super()
           
        
      
        
          
- 
            
              3
            
            
              
            
            
        @proof = proof
           
        
      
        
          
- 
            
              3
            
            
              
            
            
        @message = message
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def call result
           
        
      
        
          
- 
            
              3
            
            
              
            
            
        result.bind do |object|
           
        
      
        
          
- 
            
              3
            
            
              
            
            
          answer = question object
           
        
      
        
          
- 
            
              3
            
            
              
                
                  then: 2
                
              
                
                  else: 1
                
              
            
            
          answer == true || answer.is_a?(Success) ? result : Failure(object)
           
        
      
        
          
- 
            
            
              
            
            
        end
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      private
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      attr_reader :proof, :message
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def question object
           
        
      
        
          
- 
            
              3
            
            
              
            
            
        splat = Marameters.categorize proof.method(message).parameters, object
           
        
      
        
          
- 
            
              3
            
            
              
            
            
        proof.public_send(message, *splat.positionals, **splat.keywords, &splat.block)
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
require "containable"
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Registers default steps.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    module Container
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      extend Containable
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :alt, Or
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :amap, Amap
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :as, As
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :bind, Bind
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :check, Check
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :fmap, Fmap
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :insert, Insert
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :map, Map
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :merge, Merge
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :tee, Tee
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :to, To
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :try, Try
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :use, Use
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      register :validate, Validate
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Wraps Dry Monads `#fmap` method as a step.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Fmap < Abstract
           
        
      
        
          
- 
            
              2
            
            
              
            
            
      def call(result) = result.fmap { |object| base_block.call object }
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Inserts elements before or after an object.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Insert < Abstract
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      LAST = -1
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def initialize(*, at: LAST)
           
        
      
        
          
- 
            
              15
            
            
              
            
            
        super(*)
           
        
      
        
          
- 
            
              15
            
            
              
            
            
        @at = at
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def call result
           
        
      
        
          
- 
            
              15
            
            
              
            
            
        result.fmap do |object|
           
        
      
        
          
- 
            
              15
            
            
              
                
                  then: 7
                
              
                
                  else: 8
                
              
            
            
          cast = object.is_a?(Array) ? object : [object]
           
        
      
        
          
- 
            
              15
            
            
              
            
            
          cast.insert(at, *base_positionals)
           
        
      
        
          
- 
            
            
              
            
            
        end
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      private
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      attr_reader :at
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Maps over an enumerable, processes each element, and answers a new enumerable.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Map < Abstract
           
        
      
        
          
- 
            
              2
            
            
              
            
            
      def call(result) = result.fmap { |collection| collection.map(&base_block) }
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Merges initialized attributes with step object for use by subsequent step.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Merge < Abstract
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def initialize(as: :step, **)
           
        
      
        
          
- 
            
              4
            
            
              
            
            
        super(**)
           
        
      
        
          
- 
            
              4
            
            
              
            
            
        @as = as
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def call result
           
        
      
        
          
- 
            
              4
            
            
              
            
            
        result.fmap do |object|
           
        
      
        
          
- 
            
              3
            
            
              
                
                  then: 1
                
              
            
            
          if object.is_a? Hash
           
        
      
        
          
- 
            
              1
            
            
              
            
            
            object.merge! base_keywords
           
        
      
        
          
- 
            
            
              
                
                  else: 2
                
              
            
            
          else
           
        
      
        
          
- 
            
              2
            
            
              
            
            
            {as => object}.merge!(base_keywords)
           
        
      
        
          
- 
            
            
              
            
            
          end
           
        
      
        
          
- 
            
            
              
            
            
        end
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      private
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      attr_reader :as
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Wraps Dry Monads `#or` method as a step.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Or < Abstract
           
        
      
        
          
- 
            
              2
            
            
              
            
            
      def call(result) = result.or { |object| base_block.call object }
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Messages operation, without any checks, while passing input through as output.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Tee < Abstract
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def initialize(operation, *, **)
           
        
      
        
          
- 
            
              5
            
            
              
            
            
        super(*, **)
           
        
      
        
          
- 
            
              5
            
            
              
            
            
        @operation = operation
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def call result
           
        
      
        
          
- 
            
              5
            
            
              
            
            
        operation.public_send(*base_positionals, **base_keywords)
           
        
      
        
          
- 
            
              5
            
            
              
            
            
        result
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      private
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      attr_reader :operation
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
require "marameters"
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Delegates to a non-callable object which automatically wraps the result if necessary.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class To < Abstract
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def initialize(object, message, **)
           
        
      
        
          
- 
            
              5
            
            
              
            
            
        super(**)
           
        
      
        
          
- 
            
              5
            
            
              
            
            
        @object = object
           
        
      
        
          
- 
            
              5
            
            
              
            
            
        @message = message
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def call result
           
        
      
        
          
- 
            
              5
            
            
              
            
            
        result.bind do |arguments|
           
        
      
        
          
- 
            
              4
            
            
              
            
            
          splat = Marameters.categorize object.method(message).parameters, arguments
           
        
      
        
          
- 
            
              4
            
            
              
            
            
          wrap object.public_send(message, *splat.positionals, **splat.keywords, &splat.block)
           
        
      
        
          
- 
            
            
              
            
            
        end
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      private
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      attr_reader :object, :message
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              5
            
            
              
                
                  then: 3
                
              
                
                  else: 1
                
              
            
            
      def wrap(result) = result.is_a?(Dry::Monads::Result) ? result : Success(result)
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Sends a risky message to an object which may pass or fail.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Try < Abstract
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def initialize(*, catch:, **)
           
        
      
        
          
- 
            
              7
            
            
              
            
            
        super(*, **)
           
        
      
        
          
- 
            
              7
            
            
              
            
            
        @catch = catch
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def call result
           
        
      
        
          
- 
            
              13
            
            
              
            
            
        result.fmap { |object| object.public_send(*base_positionals, **base_keywords) }
           
        
      
        
          
- 
            
            
              
            
            
      rescue *Array(catch) => error
           
        
      
        
          
- 
            
              2
            
            
              
            
            
        Failure error
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      private
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      attr_reader :catch
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Messages a command (or pipe) which answers a result.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Use < Abstract
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def initialize(command, **)
           
        
      
        
          
- 
            
              2
            
            
              
            
            
        super(**)
           
        
      
        
          
- 
            
              2
            
            
              
            
            
        @command = command
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              2
            
            
              
            
            
      def call(result) = result.bind { |input| command.call input }
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      private
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      attr_reader :command
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end
           
        
      
    
  
 
      
        
  
  
    
      
        
          
- 
            
            
              
            
            
# frozen_string_literal: true
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
module Pipeable
           
        
      
        
          
- 
            
              1
            
            
              
            
            
  module Steps
           
        
      
        
          
- 
            
            
              
            
            
    # Validates result via a callable contract.
           
        
      
        
          
- 
            
              1
            
            
              
            
            
    class Validate < Abstract
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def initialize contract, as: nil
           
        
      
        
          
- 
            
              5
            
            
              
            
            
        super()
           
        
      
        
          
- 
            
              5
            
            
              
            
            
        @contract = contract
           
        
      
        
          
- 
            
              5
            
            
              
            
            
        @as = as
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              5
            
            
              
            
            
      def call(result) = result.bind { |payload| cast payload }
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      private
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      attr_reader :contract, :as
           
        
      
        
          
- 
            
            
              
            
            
           
        
      
        
          
- 
            
              1
            
            
              
            
            
      def cast payload
           
        
      
        
          
- 
            
              7
            
            
              
                
                  then: 2
                
              
                
                  else: 1
                
              
            
            
        contract.call(payload).to_monad.fmap { |data| as ? data.public_send(as) : data }
           
        
      
        
          
- 
            
            
              
            
            
      end
           
        
      
        
          
- 
            
            
              
            
            
    end
           
        
      
        
          
- 
            
            
              
            
            
  end
           
        
      
        
          
- 
            
            
              
            
            
end