Class: JSON::SchemaDsl::Builder

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

Overview

TODO:

Refactor class and remove rubocop exception

Builders are used to build entity-structs. They handle building this raw data so it can then be given to the renderers which modify the structure to be valid json-schema.

Each type has an associated Builder that is a dynamically generated class. Since entity-structs are immutable, the builder updates the struct and keeps track of the latest version of the struct.

Entity definitions can mostly be treated as data input while most of the logic of building the entity tree resides in the builders. rubocop:disable Metrics/ClassLength

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(inner, scope: nil) ⇒ Builder

Returns a new instance of Builder.

See Also:



139
140
141
142
# File 'lib/json/schema_dsl/builder.rb', line 139

def initialize(inner, scope: nil)
  @inner = inner
  @scope = scope
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object (private)



167
168
169
170
171
172
173
174
# File 'lib/json/schema_dsl/builder.rb', line 167

def method_missing(meth, *args, &block)
  return super unless scope&.respond_to?(meth, true)

  maybe_child = scope.send(meth, *args, &block)
  maybe_child.respond_to?(:render) &&
    add_child(maybe_child)
  maybe_child
end

Class Attribute Details

.inner_classObject

Returns the value of attribute inner_class.



18
19
20
# File 'lib/json/schema_dsl/builder.rb', line 18

def inner_class
  @inner_class
end

Instance Attribute Details

#innerObject (readonly)

Returns the value of attribute inner.



131
132
133
# File 'lib/json/schema_dsl/builder.rb', line 131

def inner
  @inner
end

#scopeObject (readonly)

Returns the value of attribute scope.



131
132
133
# File 'lib/json/schema_dsl/builder.rb', line 131

def scope
  @scope
end

Class Method Details

.[](klass) ⇒ Object

Returns A new builder class that subclasses JSON::SchemaDsl::Builder.

Raises:

  • (ArgumentError)


22
23
24
25
26
# File 'lib/json/schema_dsl/builder.rb', line 22

def [](klass)
  raise ArgumentError, "#{klass} is not a struct." unless klass < AstNode

  registered_builders[klass] ||= klass.builder
end

.add_defaults_for(type, defaults) ⇒ Hash<Symbol, Hash>

Adds new defaults for the given type.

See Also:

  • #type_defaults


56
57
58
59
60
61
62
# File 'lib/json/schema_dsl/builder.rb', line 56

def add_defaults_for(type, defaults)
  if type_defaults[type].empty?
    type_defaults[type] = type_defaults[type].merge(defaults)
  else
    type_defaults[type].merge!(defaults)
  end
end

.build(name = nil, scope: nil, **attributes, &block) ⇒ Object

Instantiates a new builder instance with a corresponding entity and applies the attributes and block to construct a complete entity.



77
78
79
80
81
82
83
# File 'lib/json/schema_dsl/builder.rb', line 77

def build(name = nil, scope: nil, **attributes, &block)
  type     = (attributes[:type] || inner_class.infer_type)&.to_sym
  defaults = ::JSON::SchemaDsl::Builder
             .type_defaults[type].merge(name: name, type: type)
  builder  = new(inner_class.new(defaults), scope: scope)
  Docile.dsl_eval(builder, &config_block(attributes, &block))
end

.class_nameObject

nodoc



91
92
93
# File 'lib/json/schema_dsl/builder.rb', line 91

def class_name
  name || inner_class.name + 'Builder'
end

.define_builder(klass) ⇒ Object

Returns A new builder class that subclasses JSON::SchemaDsl::Builder.

See Also:

  • #[]


109
110
111
112
113
114
115
116
117
118
# File 'lib/json/schema_dsl/builder.rb', line 109

def define_builder(klass)
  Class.new(self) do
    self.inner_class = klass
    klass.schema.keys.map(&:name).each do |name|
      define_method(name) do |*args, **opts, &block|
        set(name, *args, **opts, &block)
      end
    end
  end
end

.define_builder_method(type) ⇒ Object

Defines a new method for the builder instance that mirrors the dsl method for the given type.



98
99
100
101
102
103
104
# File 'lib/json/schema_dsl/builder.rb', line 98

def define_builder_method(type)
  type_param = type.type_method_name || 'entity'
  define_method(type_param) do |name = nil, **attributes, &block|
    new_child = build_struct(type, name, **attributes, &block)
    add_child(new_child)
  end
end

.inspectObject

nodoc



86
87
88
# File 'lib/json/schema_dsl/builder.rb', line 86

def inspect
  "#<#{class_name} inner_class=#{inner_class}>"
end

.registered_buildersArray<JSON::SchemaDsl::Builder>



31
32
33
# File 'lib/json/schema_dsl/builder.rb', line 31

def registered_builders
  @registered_builders ||= {}
end

.reset_type_defaults!Hash<Symbol, Hash>

Clears the registered type defaults and returns an empty hash.

See Also:

  • #type_defaults


45
46
47
# File 'lib/json/schema_dsl/builder.rb', line 45

def reset_type_defaults!
  type_defaults.clear
end

.type_defaultsHash<Symbol, Hash>



38
39
40
# File 'lib/json/schema_dsl/builder.rb', line 38

def type_defaults
  @type_defaults ||= Hash.new { {} }
end

Instance Method Details

#renderObject

Renders the given tree structure into a hash. Note that this hash still has symbol keys. The scope used for the render is the same as the builder.

See Also:



147
148
149
# File 'lib/json/schema_dsl/builder.rb', line 147

def render
  ::JSON::SchemaDsl::Renderer.new(inner, scope).render
end