Sha256: 8e02081aeecf35d656ff6a638ce98e8cb07e96237054400989eb9dc381ad5968

Contents?: true

Size: 1.41 KB

Versions: 1

Compression:

Stored size: 1.41 KB

Contents

module Xpose
  class Decorated
    attr_reader :conf

    def initialize(**options)
      @conf = ::Xpose::Configuration.new(options.merge(permissive: true))
    end

    def value(instance, v)
      return v unless shall_decorate?(instance, v)
      if conf.decorator == :infer
        infer(v)
      elsif Class === conf.decorator
        conf.decorator.new(v)
      elsif conf.decorator.respond_to?(:call)
        conf.decorator.call(v)
      elsif Symbol === conf.decorator && class_exists?(klass_from_symbol)
        klass_from_symbol.new(v)
      else
        raise UnknownDecoratorError.new(conf.decorator)
      end
    end

    private

    def shall_decorate?(instance, v)
      return conf.decorate if [true, false].include?(conf.decorate)
      raise UnknownOptionsError.new(:decorate) unless conf.decorate.respond_to?(:call)
      instance.instance_exec &conf.decorate
    end

    def infer(v)
      if v.respond_to?(:decorate)
        v.decorate
      elsif class_exists?(klass_from_model)
        klass_from_model.new(v)
      else
        raise UnknownDecoratorError.new(conf.decorator)
      end
    end

    def klass_from_symbol
      conf.decorator.to_s.singularize.capitalize.constantize
    end

    def klass_from_model
      "#{conf.model}Decorator".constantize
    end

    def class_exists?(class_name)
      Module.const_get(class_name.to_s).is_a?(Class)
    rescue NameError
      return false
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
xpose-0.1.6 lib/xpose/decorated.rb