Sha256: 6f30fcf7d823cf3965b1c6f3b93875d7787eb56b7e244df930432d1be72e7737

Contents?: true

Size: 1.99 KB

Versions: 1

Compression:

Stored size: 1.99 KB

Contents

module SoberSwag
  module Serializer
    ##
    # Conditionally serialize one thing *or* the other thing via deciding on a condition.
    # This works by taking three elements: a "decision" proc, a "left" serializer, and a "right" serializer.
    # The decision proc takes in both the object to be serialized *and* the options hash, and returns a
    # `[:left, val]` object, or a `[:right, val]` object, which
    # then get passed on to the appropriate serializer.
    #
    # This is a very weird, not-very-Ruby-like abstraction, *upon which* we can build abstractions that are actually use for users.
    # It lets you build abstractions like "Use this serializer if a type has this class, otherwise use this other one."
    # When composed together, you can make arbitrary decision trees.
    class Conditional < Base
      ##
      # Error thrown when a chooser proc returns a non left-or-right value.
      class BadChoiceError < Error; end

      def initialize(chooser, left, right)
        @chooser = chooser
        @left = left
        @right = right
      end

      attr_reader :chooser, :left, :right

      def serialize(object, options = {})
        tag, val = chooser.call(object, options)
        case tag
        when :left
          left.serialize(val, options)
        when :right
          right.serialize(val, options)
        else
          raise BadChoiceError, "result of chooser proc was not a left or right, but a #{val.class}"
        end
      end

      ##
      # Since this could potentially serialize one of two alternatives,
      # the "type" we serialize two is *either* one alternative or the other.
      def type
        if left.type == right.type
          left.type
        else
          left.type | right.type
        end
      end

      def lazy_type
        left.lazy_type | right.lazy_type
      end

      def lazy_type?
        left.lazy_type? || right.lazy_type?
      end

      def finalize_lazy_type!
        [left, right].each(&:finalize_lazy_type!)
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
sober_swag-0.2.0 lib/sober_swag/serializer/conditional.rb