Class: Structure::Builder

Inherits:
Object
  • Object
show all
Defined in:
lib/structure/builder.rb

Overview

Builder class for accumulating attribute definitions

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeBuilder

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Builder.



12
13
14
15
16
17
18
# File 'lib/structure/builder.rb', line 12

def initialize
  @mappings = {}
  @defaults = {}
  @types = {}
  @optional = Set.new
  @non_nullable = Set.new
end

Instance Attribute Details

#after_parse_callbackObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



9
10
11
# File 'lib/structure/builder.rb', line 9

def after_parse_callback
  @after_parse_callback
end

#defaultsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



9
10
11
# File 'lib/structure/builder.rb', line 9

def defaults
  @defaults
end

#mappingsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



9
10
11
# File 'lib/structure/builder.rb', line 9

def mappings
  @mappings
end

#typesObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



9
10
11
# File 'lib/structure/builder.rb', line 9

def types
  @types
end

Instance Method Details

#after_parse {|instance| ... } ⇒ void

This method returns an undefined value.

Defines a callback to run after parsing

Examples:

Validation

after_parse do |order|
  raise "Invalid order" if order.total < 0
end

Yields:

  • (instance)

    Block that receives the parsed instance



87
88
89
# File 'lib/structure/builder.rb', line 87

def after_parse(&block)
  @after_parse_callback = block
end

#attribute(name, type = nil, from: nil, default: nil, null: true) {|value| ... } ⇒ Object

DSL method for defining attributes with optional type coercion

Examples:

With type coercion

attribute :age, Integer

With custom source key

attribute :created_at, Time, from: "CreatedAt"

With transformation block

attribute :price do |value|
  Money.new(value["amount"], value["currency"])
end

Non-nullable attribute

attribute :id, String, null: false

Parameters:

  • name (Symbol)

    The attribute name

  • type (Class, Symbol, Array, nil) (defaults to: nil)

    Type for coercion (e.g., String, :boolean, [String])

  • from (String, nil) (defaults to: nil)

    Source key in the data hash (defaults to name.to_s)

  • default (Object, nil) (defaults to: nil)

    Default value if attribute is missing

  • null (Boolean) (defaults to: true)

    Whether nil values are allowed (default: true)

Yields:

  • (value)

    Block for custom transformation

Raises:

  • (ArgumentError)

    If both type and block are provided



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/structure/builder.rb', line 43

def attribute(name, type = nil, from: nil, default: nil, null: true, &block)
  mappings[name] = (from || name).to_s
  defaults[name] = default unless default.nil?
  @non_nullable.add(name) unless null

  if type && block
    raise ArgumentError, "cannot specify both type and block for :#{name}"
  else
    types[name] = type || block
  end
end

#attribute?(name, type = nil, from: nil, default: nil, null: true) {|value| ... } ⇒ Boolean

DSL method for defining optional attributes (key can be missing from input hash)

Examples:

Optional attribute

attribute? :age, Integer

Optional with default

attribute? :status, String, default: "pending"

Optional but non-nullable when present

attribute? :name, String, null: false

Parameters:

  • name (Symbol)

    The attribute name

  • type (Class, Symbol, Array, nil) (defaults to: nil)

    Type for coercion (e.g., String, :boolean, [String])

  • from (String, nil) (defaults to: nil)

    Source key in the data hash (defaults to name.to_s)

  • default (Object, nil) (defaults to: nil)

    Default value if attribute is missing

  • null (Boolean) (defaults to: true)

    Whether nil values are allowed (default: true)

Yields:

  • (value)

    Block for custom transformation

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)

    If both type and block are provided



73
74
75
76
# File 'lib/structure/builder.rb', line 73

def attribute?(name, type = nil, from: nil, default: nil, null: true, &block)
  attribute(name, type, from: from, default: default, null: null, &block)
  @optional.add(name)
end

#attributesObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



92
# File 'lib/structure/builder.rb', line 92

def attributes = @mappings.keys

#coercions(context = nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



104
105
106
107
108
109
110
111
# File 'lib/structure/builder.rb', line 104

def coercions(context = nil)
  @types.to_h do |attr, type|
    coercion = Types.coerce(type, context)
    [attr, coercion]
  rescue ArgumentError => e
    raise ArgumentError, "#{e.message} for :#{attr}"
  end
end

#non_nullableObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



101
# File 'lib/structure/builder.rb', line 101

def non_nullable = @non_nullable.to_a

#optionalObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



95
# File 'lib/structure/builder.rb', line 95

def optional = @optional.to_a

#predicate_methodsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



114
115
116
117
118
119
120
# File 'lib/structure/builder.rb', line 114

def predicate_methods
  @types.filter_map do |name, type|
    if type == :boolean
      ["#{name}?".to_sym, name] unless name.to_s.end_with?("?")
    end
  end.to_h
end

#requiredObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



98
# File 'lib/structure/builder.rb', line 98

def required = attributes - optional