class Alba::TypedAttribute

Representing typed attributes to encapsulate logic about types

Public Class Methods

new(name:, type:, converter:) click to toggle source

@param name [Symbol, String] @param type [Symbol, Class] @param converter [Proc]

# File lib/alba/typed_attribute.rb, line 7
def initialize(name:, type:, converter:)
  @name = name
  @type = type
  @converter = case converter
               when true then default_converter
               when false, nil then null_converter
               else converter
               end
end

Public Instance Methods

value(object) click to toggle source

@param object [Object] target to check and convert type with @return [String, Integer, Boolean] type-checked or type-converted object

# File lib/alba/typed_attribute.rb, line 19
def value(object)
  value, result = check(object)
  result ? value : @converter.call(value)
rescue TypeError
  raise TypeError, "Attribute #{@name} is expected to be #{@type} but actually #{display_value_for(value)}."
end

Private Instance Methods

check(object) click to toggle source
# File lib/alba/typed_attribute.rb, line 28
def check(object)
  value = object.public_send(@name)
  type_correct = case @type
                 when :String, ->(klass) { klass == String } then value.is_a?(String)
                 when :Integer, ->(klass) { klass == Integer } then value.is_a?(Integer)
                 when :Boolean then [true, false].include?(value)
                 else
                   raise Alba::UnsupportedType, "Unknown type: #{@type}"
                 end
  [value, type_correct]
end
default_converter() click to toggle source
# File lib/alba/typed_attribute.rb, line 40
def default_converter
  case @type
  when :String, ->(klass) { klass == String }
    ->(object) { object.to_s }
  when :Integer, ->(klass) { klass == Integer }
    ->(object) { Integer(object) }
  when :Boolean
    ->(object) { !!object }
  else
    raise Alba::UnsupportedType, "Unknown type: #{@type}"
  end
end
display_value_for(value) click to toggle source
# File lib/alba/typed_attribute.rb, line 57
def display_value_for(value)
  value.nil? ? 'nil' : value.class.name
end
null_converter() click to toggle source
# File lib/alba/typed_attribute.rb, line 53
def null_converter
  ->(_) { raise TypeError }
end