lib/dry/data.rb in dry-data-0.2.1 vs lib/dry/data.rb in dry-data-0.3.0
- old
+ new
@@ -2,19 +2,24 @@
require 'date'
require 'set'
require 'dry-container'
require 'inflecto'
+require 'thread_safe/cache'
require 'dry/data/version'
require 'dry/data/container'
require 'dry/data/type'
require 'dry/data/struct'
require 'dry/data/dsl'
module Dry
module Data
+ extend Dry::Configurable
+
+ setting :namespace, self
+
class SchemaError < TypeError
def initialize(key, value)
super("#{value.inspect} (#{value.class}) has invalid type for :#{key}")
end
end
@@ -24,13 +29,18 @@
super(":#{key} is missing in Hash input")
end
end
StructError = Class.new(TypeError)
+ ConstraintError = Class.new(TypeError)
TYPE_SPEC_REGEX = %r[(.+)<(.+)>].freeze
+ def self.finalize
+ define_constants(config.namespace, container._container.keys)
+ end
+
def self.container
@container ||= Container.new
end
def self.register(name, type = nil, &block)
@@ -43,11 +53,11 @@
Type.new(klass.method(:new), klass)
)
end
def self.[](name)
- type_map.fetch(name) do
+ type_map.fetch_or_store(name) do
result = name.match(TYPE_SPEC_REGEX)
type =
if result
type_id, member_id = result[1..2]
@@ -58,16 +68,35 @@
type_map[name] = type
end
end
+ def self.define_constants(namespace, identifiers)
+ names = identifiers.map do |id|
+ parts = id.split('.')
+ [Inflecto.camelize(parts.pop), parts.map(&Inflecto.method(:camelize))]
+ end
+
+ names.map do |(klass, parts)|
+ mod = parts.reduce(namespace) do |a, e|
+ a.constants.include?(e.to_sym) ? a.const_get(e) : a.const_set(e, Module.new)
+ end
+
+ mod.const_set(klass, self[identifier((parts + [klass]).join('::'))])
+ end
+ end
+
+ def self.identifier(klass)
+ Inflecto.underscore(klass).gsub('/', '.')
+ end
+
def self.type(*args, &block)
dsl = DSL.new(container)
block ? yield(dsl) : registry[args.first]
end
def self.type_map
- @type_map ||= {}
+ @type_map ||= ThreadSafe::Cache.new
end
end
end
require 'dry/data/types' # load built-in types