lib/parametric/struct.rb in parametric-0.2.10 vs lib/parametric/struct.rb in parametric-0.2.11

- old
+ new

@@ -1,5 +1,7 @@ +# frozen_string_literal: true + require 'parametric/dsl' module Parametric class InvalidStructError < ArgumentError attr_reader :errors @@ -54,49 +56,53 @@ st end # this hook is called after schema definition in DSL module def parametric_after_define_schema(schema) - schema.fields.keys.each do |key| - define_method key do - _graph[key] + schema.fields.values.each do |field| + if field.meta_data[:schema] + if field.meta_data[:schema].is_a?(Parametric::Schema) + klass = Class.new do + include Struct + end + klass.schema = field.meta_data[:schema] + self.const_set(__class_name(field.key), klass) + klass.parametric_after_define_schema(field.meta_data[:schema]) + else + self.const_set(__class_name(field.key), field.meta_data[:schema]) + end end + self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{field.key} + _graph[:#{field.key}] + end + RUBY end end def build(attrs) attrs.each_with_object({}) do |(k, v), obj| obj[k] = wrap(k, v) end end - def parametric_build_class_for_child(key, child_schema) - klass = Class.new do - include Struct - end - klass.schema = child_schema - klass - end - def wrap(key, value) - field = schema.fields[key] - return value unless field - case value when Hash # find constructor for field - cons = field.meta_data[:schema] - if cons.kind_of?(Parametric::Schema) - klass = parametric_build_class_for_child(key, cons) - klass.parametric_after_define_schema(cons) - cons = klass - end + cons = self.const_get(__class_name(key)) cons ? cons.new(value) : value.freeze when Array value.map{|v| wrap(key, v) }.freeze else value.freeze end + end + + PLURAL_END = /s$/.freeze + + def __class_name(key) + key.to_s.split('_').map(&:capitalize).join.sub(PLURAL_END, '') end end end end