Skip to content

Commit

Permalink
Revert "Integrate with Virtus Coercion system (WIP)"
Browse files Browse the repository at this point in the history
  • Loading branch information
solnic committed Mar 18, 2015
1 parent efa363c commit df359f1
Show file tree
Hide file tree
Showing 43 changed files with 359 additions and 118 deletions.
2 changes: 0 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ source :rubygems

gemspec

gem 'virtus', '~> 0.5', :git => 'https://github.com/solnic/virtus'

SOURCE = ENV.fetch('SOURCE', :git).to_sym
REPO_POSTFIX = SOURCE == :path ? '' : '.git'
DATAMAPPER = SOURCE == :path ? Pathname(__FILE__).dirname.parent : 'https://github.com/datamapper'
Expand Down
2 changes: 1 addition & 1 deletion dm-core.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
gem.version = DataMapper::VERSION

gem.add_runtime_dependency('addressable', '~> 2.2.6')
gem.add_runtime_dependency('virtus', '~> 0.5')
gem.add_runtime_dependency('backports')

gem.add_development_dependency('rake', '~> 0.9.2')
gem.add_development_dependency('rspec', '~> 1.3.2')
Expand Down
12 changes: 3 additions & 9 deletions lib/dm-core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,6 @@ module DataMapper
module Undefined; end
end

require 'virtus'

class Virtus::Coercion::Object
def self.to_string(value)
value.nil? ? value : value.to_s
end
end

require 'dm-core/support/ext/blank'
require 'dm-core/support/ext/hash'
require 'dm-core/support/ext/object'
Expand Down Expand Up @@ -68,8 +60,10 @@ def self.to_string(value)
require 'dm-core/resource/persistence_state/deleted'
require 'dm-core/resource/persistence_state/dirty'

require 'dm-core/property'
require 'dm-core/property/invalid_value_error'
require 'dm-core/property'
require 'dm-core/property/typecast/numeric'
require 'dm-core/property/typecast/time'
require 'dm-core/property/object'
require 'dm-core/property/string'
require 'dm-core/property/binary'
Expand Down
22 changes: 11 additions & 11 deletions lib/dm-core/property.rb
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ class Property
].to_set.freeze

OPTIONS = [
:load_as, :dump_as, :coercion_method,
:load_as, :dump_as,
:accessor, :reader, :writer,
:lazy, :default, :key, :field,
:index, :unique_index,
Expand All @@ -335,8 +335,7 @@ class Property
Query::OPTIONS.to_a
).map { |name| name.to_s }

attr_reader :load_as, :dump_as, :coercion_method,
:model, :name, :instance_variable_name,
attr_reader :load_as, :dump_as, :model, :name, :instance_variable_name,
:reader_visibility, :writer_visibility, :options,
:default, :repository_name, :allow_nil, :allow_blank, :required

Expand Down Expand Up @@ -675,7 +674,11 @@ def properties

# @api semipublic
def typecast(value)
Virtus::Coercion[value.class].send(coercion_method, value)
if value.nil? || value_loaded?(value)
value
elsif respond_to?(:typecast_to_primitive)
typecast_to_primitive(value)
end
end

# Test the value to see if it is a valid value for this Property
Expand Down Expand Up @@ -773,13 +776,10 @@ def initialize(model, name, options = {})
@name = name.to_s.chomp('?').to_sym
@options = predefined_options.merge(options).freeze
@instance_variable_name = "@#{@name}".freeze
@coercion_method = @options.fetch(:coercion_method)

@load_as = self.class.load_as
@dump_as = self.class.dump_as

@field = @options[:field].freeze unless @options[:field].nil?
@default = @options[:default]
@load_as = self.class.load_as
@dump_as = @options.fetch(:dump_as, @load_as)
@field = @options[:field].freeze unless @options[:field].nil?
@default = @options[:default]

@serial = @options.fetch(:serial, false)
@key = @options.fetch(:key, @serial)
Expand Down
2 changes: 0 additions & 2 deletions lib/dm-core/property/binary.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module DataMapper
class Property
class Binary < String

if RUBY_VERSION >= "1.9"

def load(value)
Expand All @@ -15,7 +14,6 @@ def dump(value)
end

end

end # class Binary
end # class Property
end # module DataMapper
22 changes: 19 additions & 3 deletions lib/dm-core/property/boolean.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
module DataMapper
class Property
class Boolean < Object
load_as ::TrueClass
dump_as ::TrueClass
coercion_method :to_boolean
load_as ::TrueClass

TRUE_VALUES = [ 1, '1', 't', 'T', 'true', 'TRUE' ].freeze
FALSE_VALUES = [ 0, '0', 'f', 'F', 'false', 'FALSE' ].freeze
BOOLEAN_MAP = Hash[
TRUE_VALUES.product([ true ]) + FALSE_VALUES.product([ false ]) ].freeze

# @api semipublic
def value_dumped?(value)
Expand All @@ -15,6 +18,19 @@ def value_loaded?(value)
value == true || value == false
end

# Typecast a value to a true or false
#
# @param [Integer, #to_str] value
# value to typecast
#
# @return [Boolean]
# true or false constructed from value
#
# @api private
def typecast_to_primitive(value)
BOOLEAN_MAP.fetch(value, value)
end

end # class Boolean
end # class Property
end # module DataMapper
18 changes: 12 additions & 6 deletions lib/dm-core/property/class.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
module DataMapper
class Property
class Class < Object
load_as ::Class
dump_as ::Class
coercion_method :to_constant
load_as ::Class

# @api semipublic
def typecast(value)
DataMapper::Ext::Module.find_const(model, value.to_s) unless value.nil?
# Typecast a value to a Class
#
# @param [#to_s] value
# value to typecast
#
# @return [Class]
# Class constructed from value
#
# @api private
def typecast_to_primitive(value)
DataMapper::Ext::Module.find_const(model, value.to_s)
rescue NameError
value
end
Expand Down
40 changes: 37 additions & 3 deletions lib/dm-core/property/date.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,44 @@
module DataMapper
class Property
class Date < Object
load_as ::Date
dump_as ::Date
coercion_method :to_date
include Typecast::Time

load_as ::Date

# Typecasts an arbitrary value to a Date
# Handles both Hashes and Date instances.
#
# @param [Hash, #to_mash, #to_s] value
# value to be typecast
#
# @return [Date]
# Date constructed from value
#
# @api private
def typecast_to_primitive(value)
if value.respond_to?(:to_date)
value.to_date
elsif value.is_a?(::Hash) || value.respond_to?(:to_mash)
typecast_hash_to_date(value)
else
::Date.parse(value.to_s)
end
rescue ArgumentError
value
end

# Creates a Date instance from a Hash with keys :year, :month, :day
#
# @param [Hash, #to_mash] value
# value to be typecast
#
# @return [Date]
# Date constructed from hash
#
# @api private
def typecast_hash_to_date(value)
::Date.new(*extract_time(value)[0, 3])
end
end # class Date
end # class Property
end # module DataMapper
39 changes: 36 additions & 3 deletions lib/dm-core/property/date_time.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,43 @@
module DataMapper
class Property
class DateTime < Object
load_as ::DateTime
dump_as ::DateTime
coercion_method :to_datetime
include Typecast::Time

load_as ::DateTime

# Typecasts an arbitrary value to a DateTime.
# Handles both Hashes and DateTime instances.
#
# @param [Hash, #to_mash, #to_s] value
# value to be typecast
#
# @return [DateTime]
# DateTime constructed from value
#
# @api private
def typecast_to_primitive(value)
if value.is_a?(::Hash) || value.respond_to?(:to_mash)
typecast_hash_to_datetime(value)
else
::DateTime.parse(value.to_s)
end
rescue ArgumentError
value
end

# Creates a DateTime instance from a Hash with keys :year, :month, :day,
# :hour, :min, :sec
#
# @param [Hash, #to_mash] value
# value to be typecast
#
# @return [DateTime]
# DateTime constructed from hash
#
# @api private
def typecast_hash_to_datetime(value)
::DateTime.new(*extract_time(value))
end
end # class DateTime
end # class Property
end # module DataMapper
22 changes: 18 additions & 4 deletions lib/dm-core/property/decimal.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
module DataMapper
class Property
class Decimal < Numeric
load_as BigDecimal
dump_as BigDecimal
coercion_method :to_decimal
load_as BigDecimal

DEFAULT_PRECISION = 10
DEFAULT_SCALE = 0

precision(DEFAULT_PRECISION)
scale(DEFAULT_SCALE)

protected
protected

def initialize(model, name, options = {})
super
Expand All @@ -31,6 +29,22 @@ def initialize(model, name, options = {})
end
end

# Typecast a value to a BigDecimal
#
# @param [#to_str, #to_d, Integer] value
# value to typecast
#
# @return [BigDecimal]
# BigDecimal constructed from value
#
# @api private
def typecast_to_primitive(value)
if value.kind_of?(::Integer)
value.to_s.to_d
else
typecast_to_numeric(value, :to_d)
end
end
end # class Decimal
end # class Property
end # module DataMapper
2 changes: 1 addition & 1 deletion lib/dm-core/property/discriminator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def new(*args, &block)
discriminator = properties(repository_name).discriminator

if discriminator_value = args.first[discriminator.name]
model = discriminator.typecast(discriminator_value)
model = discriminator.typecast_to_primitive(discriminator_value)

if model.kind_of?(Model) && !model.equal?(self)
return model.new(*args, &block)
Expand Down
18 changes: 15 additions & 3 deletions lib/dm-core/property/float.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
module DataMapper
class Property
class Float < Numeric
load_as ::Float
dump_as ::Float
coercion_method :to_float
load_as ::Float

DEFAULT_PRECISION = 10
DEFAULT_SCALE = nil

precision(DEFAULT_PRECISION)
scale(DEFAULT_SCALE)

protected

# Typecast a value to a Float
#
# @param [#to_str, #to_f] value
# value to typecast
#
# @return [Float]
# Float constructed from value
#
# @api private
def typecast_to_primitive(value)
typecast_to_numeric(value, :to_f)
end
end # class Float
end # class Property
end # module DataMapper
18 changes: 14 additions & 4 deletions lib/dm-core/property/integer.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
module DataMapper
class Property
class Integer < Numeric
load_as ::Integer
dump_as ::Integer
coercion_method :to_integer
load_as ::Integer

accept_options :serial

protected
protected

# @api semipublic
def initialize(model, name, options = {})
Expand All @@ -17,6 +15,18 @@ def initialize(model, name, options = {})
super
end

# Typecast a value to an Integer
#
# @param [#to_str, #to_i] value
# value to typecast
#
# @return [Integer]
# Integer constructed from value
#
# @api private
def typecast_to_primitive(value)
typecast_to_numeric(value, :to_i)
end
end # class Integer
end # class Property
end # module DataMapper
Loading

0 comments on commit df359f1

Please sign in to comment.