granite-form 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +1 -1
  3. data/CHANGELOG.md +7 -0
  4. data/Rakefile +4 -0
  5. data/granite-form.gemspec +1 -0
  6. data/lib/granite/form/config.rb +10 -10
  7. data/lib/granite/form/model/associations/nested_attributes.rb +3 -3
  8. data/lib/granite/form/model/associations/reflections/references_many.rb +3 -1
  9. data/lib/granite/form/model/associations/reflections/references_one.rb +3 -1
  10. data/lib/granite/form/model/attributes/attribute.rb +1 -1
  11. data/lib/granite/form/model/attributes/base.rb +13 -16
  12. data/lib/granite/form/model/attributes/collection.rb +1 -1
  13. data/lib/granite/form/model/attributes/dictionary.rb +1 -1
  14. data/lib/granite/form/model/attributes/localized.rb +1 -1
  15. data/lib/granite/form/model/attributes/reference_many.rb +1 -1
  16. data/lib/granite/form/model/attributes/reference_one.rb +1 -9
  17. data/lib/granite/form/model/attributes/reflections/base.rb +1 -5
  18. data/lib/granite/form/model/attributes/reflections/reference_one.rb +0 -4
  19. data/lib/granite/form/model/validations/nested.rb +1 -1
  20. data/lib/granite/form/types/active_support/time_zone.rb +22 -0
  21. data/lib/granite/form/types/array.rb +17 -0
  22. data/lib/granite/form/types/big_decimal.rb +15 -0
  23. data/lib/granite/form/types/boolean.rb +38 -0
  24. data/lib/granite/form/types/date.rb +15 -0
  25. data/lib/granite/form/types/date_time.rb +15 -0
  26. data/lib/granite/form/types/float.rb +15 -0
  27. data/lib/granite/form/types/hash_with_action_controller_parameters.rb +18 -0
  28. data/lib/granite/form/types/integer.rb +13 -0
  29. data/lib/granite/form/types/object.rb +30 -0
  30. data/lib/granite/form/types/string.rb +13 -0
  31. data/lib/granite/form/types/time.rb +15 -0
  32. data/lib/granite/form/types/uuid.rb +22 -0
  33. data/lib/granite/form/types.rb +15 -0
  34. data/lib/granite/form/version.rb +1 -1
  35. data/lib/granite/form.rb +19 -118
  36. data/spec/{lib/granite → granite}/form/active_record/associations_spec.rb +0 -0
  37. data/spec/{lib/granite → granite}/form/active_record/nested_attributes_spec.rb +0 -1
  38. data/spec/{lib/granite → granite}/form/config_spec.rb +22 -10
  39. data/spec/granite/form/extensions_spec.rb +12 -0
  40. data/spec/{lib/granite → granite}/form/model/associations/embeds_many_spec.rb +0 -0
  41. data/spec/{lib/granite → granite}/form/model/associations/embeds_one_spec.rb +0 -0
  42. data/spec/{lib/granite → granite}/form/model/associations/nested_attributes_spec.rb +0 -1
  43. data/spec/{lib/granite → granite}/form/model/associations/persistence_adapters/active_record_spec.rb +0 -0
  44. data/spec/{lib/granite → granite}/form/model/associations/references_many_spec.rb +0 -0
  45. data/spec/{lib/granite → granite}/form/model/associations/references_one_spec.rb +0 -0
  46. data/spec/{lib/granite → granite}/form/model/associations/reflections/embeds_any_spec.rb +0 -0
  47. data/spec/{lib/granite → granite}/form/model/associations/reflections/embeds_many_spec.rb +0 -0
  48. data/spec/{lib/granite → granite}/form/model/associations/reflections/embeds_one_spec.rb +0 -0
  49. data/spec/{lib/granite → granite}/form/model/associations/reflections/references_many_spec.rb +0 -0
  50. data/spec/{lib/granite → granite}/form/model/associations/reflections/references_one_spec.rb +0 -0
  51. data/spec/{lib/granite → granite}/form/model/associations/validations_spec.rb +0 -0
  52. data/spec/{lib/granite → granite}/form/model/associations_spec.rb +0 -0
  53. data/spec/{lib/granite → granite}/form/model/attributes/attribute_spec.rb +4 -46
  54. data/spec/{lib/granite → granite}/form/model/attributes/base_spec.rb +11 -2
  55. data/spec/{lib/granite → granite}/form/model/attributes/collection_spec.rb +0 -0
  56. data/spec/{lib/granite → granite}/form/model/attributes/dictionary_spec.rb +0 -0
  57. data/spec/{lib/granite → granite}/form/model/attributes/localized_spec.rb +1 -1
  58. data/spec/{lib/granite → granite}/form/model/attributes/reflections/attribute_spec.rb +0 -12
  59. data/spec/{lib/granite → granite}/form/model/attributes/reflections/base_spec.rb +1 -1
  60. data/spec/{lib/granite → granite}/form/model/attributes/reflections/collection_spec.rb +0 -0
  61. data/spec/{lib/granite → granite}/form/model/attributes/reflections/dictionary_spec.rb +0 -0
  62. data/spec/{lib/granite → granite}/form/model/attributes/reflections/localized_spec.rb +0 -0
  63. data/spec/{lib/granite → granite}/form/model/attributes/reflections/represents_spec.rb +0 -0
  64. data/spec/{lib/granite → granite}/form/model/attributes/represents_spec.rb +0 -0
  65. data/spec/{lib/granite → granite}/form/model/attributes_spec.rb +0 -0
  66. data/spec/{lib/granite → granite}/form/model/callbacks_spec.rb +0 -0
  67. data/spec/{lib/granite → granite}/form/model/conventions_spec.rb +0 -0
  68. data/spec/{lib/granite → granite}/form/model/dirty_spec.rb +0 -0
  69. data/spec/{lib/granite → granite}/form/model/lifecycle_spec.rb +0 -0
  70. data/spec/{lib/granite → granite}/form/model/persistence_spec.rb +0 -0
  71. data/spec/{lib/granite → granite}/form/model/primary_spec.rb +1 -1
  72. data/spec/{lib/granite → granite}/form/model/representation_spec.rb +0 -0
  73. data/spec/{lib/granite → granite}/form/model/scopes_spec.rb +0 -0
  74. data/spec/{lib/granite → granite}/form/model/validations/associated_spec.rb +0 -0
  75. data/spec/{lib/granite → granite}/form/model/validations/nested_spec.rb +55 -11
  76. data/spec/{lib/granite → granite}/form/model/validations_spec.rb +0 -0
  77. data/spec/{lib/granite → granite}/form/model_spec.rb +0 -0
  78. data/spec/granite/form/types/active_support/time_zone_spec.rb +24 -0
  79. data/spec/granite/form/types/array_spec.rb +13 -0
  80. data/spec/granite/form/types/big_decimal_spec.rb +19 -0
  81. data/spec/granite/form/types/boolean_spec.rb +21 -0
  82. data/spec/granite/form/types/date_spec.rb +18 -0
  83. data/spec/granite/form/types/date_time_spec.rb +20 -0
  84. data/spec/granite/form/types/float_spec.rb +19 -0
  85. data/spec/granite/form/types/hash_with_action_controller_parameters_spec.rb +22 -0
  86. data/spec/granite/form/types/integer_spec.rb +18 -0
  87. data/spec/granite/form/types/object_spec.rb +40 -0
  88. data/spec/granite/form/types/string_spec.rb +13 -0
  89. data/spec/granite/form/types/time_spec.rb +31 -0
  90. data/spec/granite/form/types/uuid_spec.rb +21 -0
  91. data/spec/{lib/granite → granite}/form_spec.rb +0 -0
  92. data/spec/{shared → support/shared}/nested_attribute_examples.rb +0 -0
  93. data/spec/support/shared/type_examples.rb +7 -0
  94. metadata +147 -91
  95. data/spec/lib/granite/form/model/typecasting_spec.rb +0 -193
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df27378689a1bdcdc95593c32c65046ecaab452cc3303839979ace6f1a12ef0f
4
- data.tar.gz: 41b0ee8c8b22f1cf992e7b46c91528b4596ad6b362930c5299b6fde58a9bd2b8
3
+ metadata.gz: ebac9979a786e2a3638b1dd7b21648320c779770c10f7fe63707b38a58c0164c
4
+ data.tar.gz: 604dcf0abda92863e1503b0d977a53ca1de7a39823bfc8a4aabab8d9c6a27045
5
5
  SHA512:
6
- metadata.gz: aef5479a5c58afc85c8e68635fbd8382039c69b8235beaeda74d5caf320540c2fd8aac330f70f4c031abfd37d6a214c3acab0086c9c0a1d3843aedd7aab5a1db
7
- data.tar.gz: 5fcc7f498c8685167096ec9d835c6cc80efec7915b17c32aa27f8e912776d2ef25e215ed24c076e7c8e4cb32790eba060d8a7aac827ff1c2cd8d93819b7ae7e2
6
+ metadata.gz: cfc2c624834fe5d0ad4fadb903e6b9a38eed17778cea3c0cf9430437fb095436429c1a0941fd418e143805b064c1a74c0c959fb57493d96fb9602cdca625f36d
7
+ data.tar.gz: 4937e3d02a378edf48daa770799206b3ecdb91ee71ed1025169e6e3bf4a25bc157c01aea9db54dcb70645728eeb0055ca42be7db23258f0b7f2744d8f7415dd9
data/.rubocop_todo.yml CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  # Offense count: 19
10
10
  Metrics/AbcSize:
11
- Max: 54
11
+ Max: 55
12
12
 
13
13
  # Offense count: 2
14
14
  # Configuration parameters: CountComments.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # master
2
2
 
3
+ ## Next
4
+ ## v0.2.0
5
+
6
+ - Replace typecasters with proper type definitions.
7
+ - Instead of `typecaster(type) { |value, _| ... }` you'll have to use `typecaster(type) { |value| ... }`.
8
+ - Consequently you can access type definition in typecaster, e.g. `typecaster('Object') { |value| value if value.class < type }`, here `type` comes from type definition.
9
+
3
10
  ## v0.1.1
4
11
 
5
12
  - Fixed represented error message copying when represented model uses symbols for `message`.
data/Rakefile CHANGED
@@ -1,6 +1,10 @@
1
1
  require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
+ require 'bump/tasks'
3
4
 
4
5
  RSpec::Core::RakeTask.new(:spec)
5
6
 
6
7
  task default: :spec
8
+
9
+ Bump.tag_by_default = true
10
+ Bump.changelog = true
data/granite-form.gemspec CHANGED
@@ -17,6 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.add_development_dependency 'actionpack', '>= 4.0'
18
18
  gem.add_development_dependency 'activerecord', '>= 4.0'
19
19
  gem.add_development_dependency 'appraisal'
20
+ gem.add_development_dependency 'bump'
20
21
  gem.add_development_dependency 'database_cleaner'
21
22
  gem.add_development_dependency 'rake'
22
23
  gem.add_development_dependency 'rspec', '~> 3.7.0'
@@ -4,7 +4,7 @@ module Granite
4
4
  include Singleton
5
5
 
6
6
  attr_accessor :include_root_in_json, :i18n_scope, :logger, :primary_attribute, :base_class, :base_concern,
7
- :_normalizers, :_typecasters
7
+ :_normalizers, :types
8
8
 
9
9
  def self.delegated
10
10
  public_instance_methods - superclass.public_instance_methods - Singleton.public_instance_methods
@@ -16,7 +16,7 @@ module Granite
16
16
  @logger = Logger.new(STDERR)
17
17
  @primary_attribute = :id
18
18
  @_normalizers = {}
19
- @_typecasters = {}
19
+ @types = {}
20
20
  end
21
21
 
22
22
  def normalizer(name, &block)
@@ -27,16 +27,16 @@ module Granite
27
27
  end
28
28
  end
29
29
 
30
- def typecaster(*classes, &block)
31
- classes = classes.flatten
32
- if block
33
- _typecasters[classes.first.to_s.camelize] = block
34
- else
35
- _typecasters[classes.detect do |klass|
36
- _typecasters[klass.to_s.camelize]
37
- end.to_s.camelize] or raise TypecasterMissing, classes
30
+ def typecaster(class_name, &block)
31
+ types[class_name.to_s.camelize] = Class.new(Types::Object) do
32
+ define_method(:typecast, &block)
38
33
  end
39
34
  end
35
+
36
+ def type_for(klass)
37
+ key = klass.ancestors.grep(Class).map(&:to_s).find(&types) or raise TypecasterMissing, klass
38
+ types.fetch(key)
39
+ end
40
40
  end
41
41
  end
42
42
  end
@@ -74,7 +74,7 @@ module Granite
74
74
  primary_attribute_name = primary_name_for(association.reflection.klass)
75
75
  if existing_record
76
76
  primary_attribute = existing_record.attribute(primary_attribute_name)
77
- primary_attribute_value = primary_attribute.typecast(attributes[primary_attribute_name]) if primary_attribute
77
+ primary_attribute_value = primary_attribute.type_definition.ensure_type(attributes[primary_attribute_name]) if primary_attribute
78
78
  end
79
79
 
80
80
  if existing_record && (!primary_attribute || options[:update_only] || existing_record.primary_attribute == primary_attribute_value)
@@ -123,7 +123,7 @@ module Granite
123
123
  else
124
124
  existing_record = association.target.detect do |record|
125
125
  primary_attribute_value = record.attribute(primary_attribute_name)
126
- .typecast(attributes[primary_attribute_name])
126
+ .type_definition.ensure_type(attributes[primary_attribute_name])
127
127
  record.primary_attribute == primary_attribute_value
128
128
  end
129
129
  if existing_record
@@ -162,7 +162,7 @@ module Granite
162
162
  end
163
163
 
164
164
  def self.destroy_flag?(hash)
165
- Granite::Form.typecaster(Boolean).call(hash[DESTROY_ATTRIBUTE])
165
+ Types::Boolean.typecast(hash[DESTROY_ATTRIBUTE])
166
166
  end
167
167
 
168
168
  def self.reject_new_object?(object, association_name, attributes, options)
@@ -12,7 +12,9 @@ module Granite
12
12
 
13
13
  target.add_attribute(
14
14
  Granite::Form::Model::Attributes::Reflections::ReferenceMany,
15
- reflection.reference_key, association: name
15
+ reflection.reference_key,
16
+ type: reflection.persistence_adapter.primary_key_type,
17
+ association: name
16
18
  )
17
19
 
18
20
  reflection
@@ -14,7 +14,9 @@ module Granite
14
14
 
15
15
  target.add_attribute(
16
16
  Granite::Form::Model::Attributes::Reflections::ReferenceOne,
17
- reflection.reference_key, association: name
17
+ reflection.reference_key,
18
+ type: reflection.persistence_adapter.primary_key_type,
19
+ association: name
18
20
  )
19
21
 
20
22
  reflection
@@ -14,7 +14,7 @@ module Granite
14
14
 
15
15
  def read
16
16
  variable_cache(:value) do
17
- normalize(enumerize(typecast(read_before_type_cast)))
17
+ normalize(enumerize(type_definition.ensure_type(read_before_type_cast)))
18
18
  end
19
19
  end
20
20
 
@@ -3,19 +3,16 @@ module Granite
3
3
  module Model
4
4
  module Attributes
5
5
  class Base
6
- attr_reader :name, :owner
7
- delegate :type, :typecaster, :readonly, to: :reflection
6
+ attr_reader :owner, :reflection
7
+ delegate :name, :readonly, to: :reflection
8
+ delegate :type, to: :type_definition
8
9
 
9
- def initialize(name, owner)
10
- @name = name
10
+ def initialize(reflection, owner)
11
+ @reflection = reflection
11
12
  @owner = owner
12
13
  @origin = :default
13
14
  end
14
15
 
15
- def reflection
16
- @owner.class._attributes[name]
17
- end
18
-
19
16
  def write_value(value, origin: :user)
20
17
  reset
21
18
  @origin = origin
@@ -55,18 +52,14 @@ module Granite
55
52
  !(read.respond_to?(:zero?) ? read.zero? : read.blank?)
56
53
  end
57
54
 
58
- def typecast(value)
59
- if value.instance_of?(type)
60
- value
61
- else
62
- typecaster.call(value, self) unless value.nil?
63
- end
64
- end
65
-
66
55
  def readonly?
67
56
  !!(readonly.is_a?(Proc) ? evaluate(&readonly) : readonly)
68
57
  end
69
58
 
59
+ def type_definition
60
+ @type_definition ||= build_type_definition(reflection.type)
61
+ end
62
+
70
63
  def inspect_attribute
71
64
  value = case read
72
65
  when Date, Time, DateTime
@@ -103,6 +96,10 @@ module Granite
103
96
 
104
97
  private
105
98
 
99
+ def build_type_definition(type)
100
+ Granite::Form.type_for(type).new(type, reflection, owner)
101
+ end
102
+
106
103
  def evaluate(*args, &block)
107
104
  if block.arity >= 0 && block.arity <= args.length
108
105
  owner.instance_exec(*args.first(block.arity), &block)
@@ -5,7 +5,7 @@ module Granite
5
5
  class Collection < Attribute
6
6
  def read
7
7
  @value ||= normalize(read_before_type_cast.map do |value|
8
- enumerize(typecast(value))
8
+ enumerize(type_definition.ensure_type(value))
9
9
  end)
10
10
  end
11
11
 
@@ -11,7 +11,7 @@ module Granite
11
11
  hash = hash.stringify_keys.slice(*keys) if keys.present?
12
12
 
13
13
  normalize(Hash[hash.map do |key, value|
14
- [key, enumerize(typecast(value))]
14
+ [key, enumerize(type_definition.ensure_type(value))]
15
15
  end].with_indifferent_access).with_indifferent_access
16
16
  end
17
17
  end
@@ -5,7 +5,7 @@ module Granite
5
5
  class Localized < Attribute
6
6
  def read
7
7
  @value ||= Hash[read_before_type_cast.map do |locale, value|
8
- [locale.to_s, normalize(enumerize(typecast(value)))]
8
+ [locale.to_s, normalize(enumerize(type_definition.ensure_type(value)))]
9
9
  end]
10
10
  end
11
11
 
@@ -5,7 +5,7 @@ module Granite
5
5
  class ReferenceMany < ReferenceOne
6
6
  def type_casted_value
7
7
  variable_cache(:value) do
8
- read_before_type_cast.map { |id| typecast(id) }
8
+ read_before_type_cast.map { |id| type_definition.ensure_type(id) }
9
9
  end
10
10
  end
11
11
 
@@ -24,7 +24,7 @@ module Granite
24
24
 
25
25
  def type_casted_value
26
26
  variable_cache(:value) do
27
- typecast(read_before_type_cast)
27
+ type_definition.ensure_type(read_before_type_cast)
28
28
  end
29
29
  end
30
30
 
@@ -32,14 +32,6 @@ module Granite
32
32
  @value_cache
33
33
  end
34
34
 
35
- def type
36
- @type ||= association.reflection.persistence_adapter.primary_key_type
37
- end
38
-
39
- def typecaster
40
- @typecaster ||= Granite::Form.typecaster(type.ancestors.grep(Class))
41
- end
42
-
43
35
  private
44
36
 
45
37
  def association
@@ -27,7 +27,7 @@ module Granite
27
27
  end
28
28
 
29
29
  def build_attribute(owner, raw_value = Granite::Form::UNDEFINED)
30
- attribute = self.class.attribute_class.new(name, owner)
30
+ attribute = self.class.attribute_class.new(self, owner)
31
31
  attribute.write_value(raw_value, origin: :persistence) unless raw_value == Granite::Form::UNDEFINED
32
32
  attribute
33
33
  end
@@ -43,10 +43,6 @@ module Granite
43
43
  end
44
44
  end
45
45
 
46
- def typecaster
47
- @typecaster ||= Granite::Form.typecaster(type.ancestors.grep(Class))
48
- end
49
-
50
46
  def readonly
51
47
  @readonly ||= options[:readonly]
52
48
  end
@@ -30,10 +30,6 @@ module Granite
30
30
  RUBY
31
31
  end
32
32
 
33
- def type
34
- Object
35
- end
36
-
37
33
  def inspect_reflection
38
34
  "#{name}: (reference)"
39
35
  end
@@ -19,7 +19,7 @@ module Granite
19
19
  def self.import_errors(from, to, prefix)
20
20
  from.each do |error|
21
21
  key = "#{prefix}.#{error.attribute}"
22
- to.import(error, attribute: key) unless to.added?(key, error.type, error.options)
22
+ to.import(error, attribute: key) unless to.messages_for(key).include?(error.message)
23
23
  end
24
24
  end
25
25
  else
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ module ActiveSupport
7
+ class TimeZone < Float
8
+ def typecast(value)
9
+ case value
10
+ when ::ActiveSupport::TimeZone
11
+ value
12
+ when ::TZInfo::Timezone
13
+ ::ActiveSupport::TimeZone[value.name]
14
+ when ::String, ::Numeric, ::ActiveSupport::Duration
15
+ ::ActiveSupport::TimeZone[super || value]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Array < Object
7
+ def typecast(value)
8
+ if value.is_a?(::String)
9
+ value.split(',').map(&:strip)
10
+ else
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class BigDecimal < Object
7
+ def typecast(value)
8
+ BigDecimal(Float(value).to_s) if value
9
+ rescue ArgumentError, TypeError
10
+ nil
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Boolean < Object
7
+ MAPPING = {
8
+ 1 => true,
9
+ 0 => false,
10
+ '1' => true,
11
+ '0' => false,
12
+ 't' => true,
13
+ 'f' => false,
14
+ 'T' => true,
15
+ 'F' => false,
16
+ true => true,
17
+ false => false,
18
+ 'true' => true,
19
+ 'false' => false,
20
+ 'TRUE' => true,
21
+ 'FALSE' => false,
22
+ 'y' => true,
23
+ 'n' => false,
24
+ 'yes' => true,
25
+ 'no' => false
26
+ }.freeze
27
+
28
+ def self.typecast(value)
29
+ MAPPING[value]
30
+ end
31
+
32
+ def typecast(value)
33
+ self.class.typecast(value)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Date < Object
7
+ def typecast(value)
8
+ value.try(:to_date)
9
+ rescue ArgumentError
10
+ nil
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class DateTime < Object
7
+ def typecast(value)
8
+ value.try(:to_datetime)
9
+ rescue ArgumentError
10
+ nil
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Float < Object
7
+ def typecast(value)
8
+ Float(value)
9
+ rescue ArgumentError, TypeError
10
+ nil
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class HashWithActionControllerParameters < Object
7
+ def typecast(value)
8
+ case value
9
+ when ActionController::Parameters
10
+ value.to_h if value.permitted?
11
+ when ::Hash then
12
+ value
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Integer < Float
7
+ def typecast(value)
8
+ super.try(:to_i)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Object
7
+ attr_reader :reflection, :owner, :type
8
+ delegate :name, to: :reflection
9
+
10
+ def initialize(type, reflection, owner)
11
+ @type = type
12
+ @reflection = reflection
13
+ @owner = owner
14
+ end
15
+
16
+ def ensure_type(value)
17
+ if value.instance_of?(type)
18
+ value
19
+ elsif !value.nil?
20
+ typecast(value)
21
+ end
22
+ end
23
+
24
+ def typecast(value)
25
+ value if value.is_a?(type)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class String < Object
7
+ def typecast(value)
8
+ value.to_s
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Time < Object
7
+ def typecast(value)
8
+ value.is_a?(::String) && ::Time.zone ? ::Time.zone.parse(value) : value.try(:to_time)
9
+ rescue ArgumentError
10
+ nil
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class UUID < Object
7
+ def typecast(value)
8
+ case value
9
+ when UUIDTools::UUID
10
+ Granite::Form::UUID.parse_raw value.raw
11
+ when Granite::Form::UUID
12
+ value
13
+ when ::String
14
+ Granite::Form::UUID.parse_string value
15
+ when ::Integer
16
+ Granite::Form::UUID.parse_int value
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'granite/form/types/object'
4
+ require 'granite/form/types/array'
5
+ require 'granite/form/types/big_decimal'
6
+ require 'granite/form/types/boolean'
7
+ require 'granite/form/types/date'
8
+ require 'granite/form/types/date_time'
9
+ require 'granite/form/types/hash_with_action_controller_parameters'
10
+ require 'granite/form/types/float'
11
+ require 'granite/form/types/integer'
12
+ require 'granite/form/types/string'
13
+ require 'granite/form/types/time'
14
+ require 'granite/form/types/uuid'
15
+ require 'granite/form/types/active_support/time_zone'
@@ -1,5 +1,5 @@
1
1
  module Granite
2
2
  module Form
3
- VERSION = '0.1.1'.freeze
3
+ VERSION = '0.2.0'.freeze
4
4
  end
5
5
  end