Class: Desiru::Field

Inherits:
Object
  • Object
show all
Defined in:
lib/desiru/field.rb

Overview

Represents a field in a signature with type information and metadata

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, type = :string, description: nil, optional: false, default: nil, validator: nil, literal_values: nil, element_type: nil, original_type: nil) ⇒ Field

Returns a new instance of Field.



11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/desiru/field.rb', line 11

def initialize(name, type = :string, description: nil, optional: false, default: nil, validator: nil,
               literal_values: nil, element_type: nil, original_type: nil)
  @name = name.to_sym
  @type = normalize_type(type)
  @original_type = original_type || type.to_s
  @description = description
  @optional = optional
  @default = default
  @literal_values = literal_values&.map(&:freeze)&.freeze if literal_values
  @element_type = element_type
  @validator = validator || default_validator
end

Instance Attribute Details

#defaultObject (readonly)

Returns the value of attribute default.



6
7
8
# File 'lib/desiru/field.rb', line 6

def default
  @default
end

#descriptionObject (readonly)

Returns the value of attribute description.



6
7
8
# File 'lib/desiru/field.rb', line 6

def description
  @description
end

#element_typeObject (readonly)

Returns the value of attribute element_type.



6
7
8
# File 'lib/desiru/field.rb', line 6

def element_type
  @element_type
end

#literal_valuesObject (readonly)

Returns the value of attribute literal_values.



6
7
8
# File 'lib/desiru/field.rb', line 6

def literal_values
  @literal_values
end

#nameObject (readonly)

Returns the value of attribute name.



6
7
8
# File 'lib/desiru/field.rb', line 6

def name
  @name
end

#optionalObject (readonly) Also known as: optional?

Returns the value of attribute optional.



6
7
8
# File 'lib/desiru/field.rb', line 6

def optional
  @optional
end

#original_typeObject (readonly)

Returns the value of attribute original_type.



6
7
8
# File 'lib/desiru/field.rb', line 6

def original_type
  @original_type
end

#typeObject (readonly)

Returns the value of attribute type.



6
7
8
# File 'lib/desiru/field.rb', line 6

def type
  @type
end

#validatorObject (readonly)

Returns the value of attribute validator.



6
7
8
# File 'lib/desiru/field.rb', line 6

def validator
  @validator
end

Instance Method Details

#coerce(value) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/desiru/field.rb', line 33

def coerce(value)
  return default if value.nil? && !default.nil?
  return value if value.nil? && optional

  case type
  when :string
    value.to_s
  when :int, :integer
    value.to_i
  when :float
    value.to_f
  when :bool, :boolean
    case value.to_s.downcase
    when 'true', 'yes', '1', 't'
      true
    when 'false', 'no', '0', 'f'
      false
    else
      !value.nil?
    end
  when :literal
    # For literal types, ensure the value is a string and matches one of the allowed values
    coerced = value.to_s
    unless literal_values.include?(coerced)
      raise ValidationError, "Value '#{coerced}' is not one of allowed values: #{literal_values.join(', ')}"
    end

    coerced
  when :list, :array
    array_value = Array(value)
    # If we have an element type, coerce each element
    if element_type && element_type[:type] == :literal
      array_value.map do |elem|
        coerced_elem = elem.to_s
        unless element_type[:literal_values].include?(coerced_elem)
          allowed = element_type[:literal_values].join(', ')
          raise ValidationError,
                "Array element '#{coerced_elem}' is not one of allowed values: #{allowed}"
        end

        coerced_elem
      end
    else
      array_value
    end
  when :hash, :dict
    value.is_a?(Hash) ? value : {}
  else
    value
  end
end

#to_hObject



85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/desiru/field.rb', line 85

def to_h
  result = {
    name: name,
    type: type,
    description: description,
    optional: optional,
    default: default
  }
  result[:literal_values] = literal_values if literal_values
  result[:element_type] = element_type if element_type
  result.compact
end

#valid?(value) ⇒ Boolean

Returns:

  • (Boolean)

Raises:



24
25
26
27
28
29
30
31
# File 'lib/desiru/field.rb', line 24

def valid?(value)
  return true if optional && value.nil?
  return true if value.nil? && !default.nil?

  raise ValidationError, validation_error_message(value) unless validator.call(value)

  true
end