Sha256: 49e4947dd86f47b6bdbcad99eab6ef7d45c58ec3737e1a3e188673a6ef5f3634

Contents?: true

Size: 1.83 KB

Versions: 2

Compression:

Stored size: 1.83 KB

Contents

# frozen_string_literal: true

require "uri"
require "addressable/uri"

module ReSorcery
  module Linked
    class LinkClassFactory
      class << self
        include Decoder::BuiltinDecoders

        def make_link_class
          fields = build_fields

          Class.new do
            include Fielded

            def initialize(args)
              @args = args
            end

            fields.each { |(name, decoder, value)| field name, decoder, value }
          end
        end

        private

        def valid_rels
          ReSorcery.configuration.fetch(:link_rels)
        end

        def valid_methods
          ReSorcery.configuration.fetch(:link_methods)
        end

        def uri_able
          is(URI, Addressable::URI).or_else do
            is(String).and_then do
              Decoder.new do |u|
                ok(Addressable::URI.parse(u))
              rescue Addressable::URI::InvalidURIError
                err("Not a valid URI: #{u}")
              end
            end
          end
        end

        def str_or_sym
          is(String, Symbol).map(&:to_s)
        end

        def rel_decoder
          str_or_sym.and_then { |v| Decoder.new { is(*valid_rels).test(v) } }
        end

        def method_decoder
          str_or_sym.and_then { |v| Decoder.new { is(*valid_methods).test(v) } }
        end

        def build_fields
          default_method = ReSorcery.configuration.fetch(:default_link_method).call(valid_methods)
          default_type = ReSorcery.configuration.fetch(:default_link_type)

          [
            [:rel, rel_decoder, -> { @args[:rel] }],
            [:href, uri_able, -> { @args[:href] }],
            [:method, method_decoder, -> { @args.fetch(:method, default_method) }],
            [:type, String, -> { @args.fetch(:type, default_type) }],
          ]
        end
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
re_sorcery-0.3.0 lib/re_sorcery/linked/link_class_factory.rb
re_sorcery-0.2.0 lib/re_sorcery/linked/link_class_factory.rb