rice_bubble 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ff1a10fe0388c60a178246ee4c45a005292355ec741b9f175b56c8ba393b060
4
- data.tar.gz: 35c94ec3a32ea7187b031eaf4341c59ad4a55649510bece671a52b480a10c2c5
3
+ metadata.gz: 9cbf4c6ade525140da24d50b1f12bf1a0d6bd0d8bd5e5b0b314204e8a086e04f
4
+ data.tar.gz: 2bb3ea6274dcb3859a7d56129554454dd888a4354f5b9500a1fbde8606e7e122
5
5
  SHA512:
6
- metadata.gz: 1eb7c799044b2d70f6f13a2066d175b4ff09965b19b11d91c36493509d579e6e9ea6ebbeb4cfe1d897faf5aded93bc74ea5e955db81fc396bda9a292689537c3
7
- data.tar.gz: 9bd2f3aa7f5c6c70ebb5c8afc1d2ca2d4ee95e2978c5491c5a6a1e225ce31c4f3ea5e908a933fa48d74e1cea4d437e131f1718c5e0c496df7c7bf0f99196699b
6
+ metadata.gz: 26a31683aec0406224411ef415cfe70ce1d497223fd9c0e209c8835f1003e2abf33b8cad26a4cd65a521c6dc5726386a0887d6041d4b94065e6204ccb3a21394
7
+ data.tar.gz: 528efe018c746fcd2b24bb88267b7804bfa0195a6034acf2b5f81405a70857bbd3d2ef02a8c4d46b7567a6e8662e85d52ce4bfdb9630e533d6161431d915efdd
data/.rubocop.yml CHANGED
@@ -13,7 +13,7 @@ Layout/FirstHashElementIndentation:
13
13
  Layout/LineLength:
14
14
  Max: 80
15
15
  AllowedPatterns:
16
- - '^\s*#'
16
+ - ^\s*[#']
17
17
 
18
18
  Layout/MultilineMethodCallIndentation:
19
19
  EnforcedStyle: indented
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rice_bubble (0.1.1)
4
+ rice_bubble (0.1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -12,22 +12,17 @@ module RiceBubble
12
12
  !which(value).nil?
13
13
  end
14
14
 
15
- def validate!(value, path:, **)
16
- member = which(value)
17
- return unless member.nil?
18
-
19
- expected = "one of [#{members.map(&:description).join(", ")}]"
20
- raise ValidationError,
21
- "#{path} expected #{expected} but received #{value.inspect}"
22
- end
23
-
24
- def coerce(value)
25
- which(value)&.coerce(value) || value
15
+ def call(value, path: '')
16
+ super(which(value)&.call(value, path:) || value, path:)
26
17
  end
27
18
 
28
19
  def which(value)
29
20
  members.find { |member| member.valid?(value) }
30
21
  end
22
+
23
+ def description
24
+ "one of [#{members.map(&:description).join(", ")}]"
25
+ end
31
26
  end
32
27
  end
33
28
  end
@@ -16,19 +16,11 @@ module RiceBubble
16
16
  end
17
17
  end
18
18
 
19
- def validate!(_value, coerced:, path:)
20
- coerced.each.with_index do |child, index|
21
- members.validate!(
22
- child,
23
- coerced: members.coerce(child),
24
- path: "#{path}[#{index}]"
25
- )
19
+ def call(value, path: '')
20
+ (value || []).map.with_index do |child, index|
21
+ members.call(child, path: "#{path}[#{index}]")
26
22
  end
27
23
  end
28
-
29
- def coerce(value)
30
- value.respond_to?(:to_a) ? value.to_a : value
31
- end
32
24
  end
33
25
  end
34
26
  end
@@ -11,29 +11,24 @@ module RiceBubble
11
11
  elsif object.respond_to?(name)
12
12
  object.public_send(name)
13
13
  else
14
- object[name]
14
+ object[name] || object[name.to_s]
15
15
  end
16
16
  end
17
17
 
18
- def valid?(_value)
19
- true
18
+ def valid?(value)
19
+ valid_types.any? { |t| value.is_a?(t) }
20
20
  end
21
21
 
22
- def coerce(value)
23
- value
24
- end
25
-
26
- def validate!(value, coerced:, path:)
27
- return if valid?(coerced)
28
-
29
- raise ValidationError,
30
- "#{path} expected #{description} but received #{value.inspect}"
22
+ def valid_types
23
+ [::Object]
31
24
  end
32
25
 
33
26
  def call(value, path: '')
34
- coerced = coerce(value)
35
- validate!(value, coerced:, path:)
36
- coerced
27
+ if valid?(value)
28
+ value
29
+ else
30
+ validation_error(value:, path:)
31
+ end
37
32
  end
38
33
 
39
34
  def optional
@@ -57,6 +52,10 @@ module RiceBubble
57
52
  class_or_instance
58
53
  end
59
54
  end
55
+
56
+ def validation_error(value:, path: '')
57
+ raise ValidationError.new(value:, path:, attribute: self)
58
+ end
60
59
  end
61
60
  end
62
61
  end
@@ -1,10 +1,6 @@
1
1
  module RiceBubble
2
2
  class Attributes
3
3
  class Boolean < Base
4
- def validate!(value, path:, **)
5
- super(value, coerced: value, path:)
6
- end
7
-
8
4
  def valid?(value)
9
5
  [true, false].include?(value)
10
6
  end
@@ -1,14 +1,12 @@
1
- require 'date'
2
-
3
1
  module RiceBubble
4
2
  class Attributes
5
3
  class Date < Base
6
- def valid?(value)
7
- value.respond_to?(:to_date)
4
+ def call(value, path: '')
5
+ super(value.to_date, path:)
8
6
  end
9
7
 
10
- def coerce(value)
11
- value.respond_to?(:to_date) ? value.to_date : value
8
+ def valid_types
9
+ [::Date, ::Time, ::DateTime]
12
10
  end
13
11
  end
14
12
  end
@@ -1,27 +1,20 @@
1
1
  module RiceBubble
2
2
  class Attributes
3
3
  class Datetime < Base
4
- def valid?(value)
5
- return false unless valid_datetime?(value)
6
-
7
- value.respond_to?(:to_datetime)
4
+ def call(value, path: '')
5
+ super(coerce(value), path:)
8
6
  end
9
7
 
10
8
  def coerce(value)
11
- return nil unless valid_datetime?(value)
12
-
13
- value.respond_to?(:to_datetime) ? value.to_datetime : value
9
+ if !value.respond_to?(:to_datetime) || value.is_a?(::Date)
10
+ value
11
+ else
12
+ value.to_datetime
13
+ end
14
14
  end
15
15
 
16
- private
17
-
18
- def valid_datetime?(value)
19
- case value
20
- when ::Time then true
21
- when ::DateTime then true
22
- when ::Date then false
23
- else value.respond_to?(:to_datetime)
24
- end
16
+ def valid_types
17
+ [::Time, ::DateTime]
25
18
  end
26
19
  end
27
20
  end
@@ -3,16 +3,20 @@ module RiceBubble
3
3
  class Integer < Number
4
4
  attr_reader :min, :max
5
5
 
6
- def valid?(value)
7
- value.is_a?(::Integer) && super
6
+ def initialize(min: nil, max: nil, **options, &)
7
+ super(**options, &)
8
+ @min = min
9
+ @max = max
10
+ end
11
+
12
+ def valid_types
13
+ [::Integer]
8
14
  end
9
15
 
10
- def coerce(value)
11
- case value
12
- when nil then nil
13
- when ::String then value.match?(/\A-?\d+\z/) ? value.to_i : value
14
- else value.respond_to?(:to_i) ? value.to_i : value
15
- end
16
+ def valid?(value)
17
+ super &&
18
+ (!min || value >= min) &&
19
+ (!max || value <= max)
16
20
  end
17
21
  end
18
22
  end
@@ -9,8 +9,12 @@ module RiceBubble
9
9
  @max = max
10
10
  end
11
11
 
12
+ def valid_types
13
+ [::Numeric]
14
+ end
15
+
12
16
  def valid?(value)
13
- value.is_a?(::Numeric) &&
17
+ super &&
14
18
  !min&.send(:>, value) &&
15
19
  !max&.send(:<, value)
16
20
  end
@@ -16,17 +16,12 @@ module RiceBubble
16
16
  end
17
17
  end
18
18
 
19
- def validate!(value, path:, **)
20
- children.each do |name, attr|
21
- child = attr.fetch(value, name)
22
- coerced = attr.coerce(child)
23
- attr.validate!(child, coerced:, path: "#{path}.#{name}")
19
+ def call(value, path: '')
20
+ children.to_h do |name, attr|
21
+ [name,
22
+ attr.call(value[name] || value[name.to_s], path: "#{path}.#{name}")]
24
23
  end
25
24
  end
26
-
27
- def coerce(value)
28
- children.map { |name, attr| attr.coerce(attr.fetch(value, name)) }
29
- end
30
25
  end
31
26
  end
32
27
  end
@@ -9,17 +9,13 @@ module RiceBubble
9
9
  end
10
10
 
11
11
  def valid?(value)
12
- value.nil? || child.valid?(child.coerce(value))
12
+ value.nil? || child.valid?(value)
13
13
  end
14
14
 
15
15
  def call(value, path: '')
16
16
  value && child.call(value, path:)
17
17
  end
18
18
 
19
- def coerce(value)
20
- value && child.coerce(value)
21
- end
22
-
23
19
  def description
24
20
  "#{child.description} (optional)"
25
21
  end
@@ -5,15 +5,15 @@ module RiceBubble
5
5
 
6
6
  def initialize(serializer, &)
7
7
  super(&)
8
- @serializer = serializer.new
8
+ @serializer = serializer
9
9
  end
10
10
 
11
11
  def valid?(value)
12
12
  serializer.valid?(value)
13
13
  end
14
14
 
15
- def validate!(value, path:, **)
16
- serializer.validate!(value, path:)
15
+ def call(value, path: '')
16
+ serializer.call(value, path:)
17
17
  end
18
18
  end
19
19
  end
@@ -10,19 +10,19 @@ module RiceBubble
10
10
  @format = format
11
11
  end
12
12
 
13
- def valid?(value)
14
- value.is_a?(::String) &&
15
- !min&.send(:>, value.length) &&
16
- !max&.send(:<, value.length) &&
17
- (!format || format.match?(value))
13
+ def valid_types
14
+ [::String, Symbol]
18
15
  end
19
16
 
20
- def call(value, path: '')
21
- super(value.to_s, path:)
17
+ def valid?(value)
18
+ super &&
19
+ !min&.send(:>, value.to_s.length) &&
20
+ !max&.send(:<, value.to_s.length) &&
21
+ (!format || format.match?(value.to_s))
22
22
  end
23
23
 
24
- def coerce(value)
25
- value.respond_to?(:to_s) ? value.to_s : value
24
+ def call(value, path: '')
25
+ super.to_s
26
26
  end
27
27
 
28
28
  def description
@@ -11,7 +11,7 @@ module RiceBubble
11
11
  self.class.new(object_to_serialize).call(path:)
12
12
  elsif object
13
13
  self.class.attributes.map do |name, attr|
14
- attr.call(fetch(name), path: path || self.class.name)
14
+ attr.call(fetch(name), path: "#{path || self.class.name}.#{name}")
15
15
  end
16
16
  else
17
17
  raise ArgumentError, 'no object to serialize'
@@ -32,23 +32,6 @@ module RiceBubble
32
32
  end
33
33
  end
34
34
 
35
- def validate!(object, path: '', **)
36
- path = self.class.name if path.empty?
37
-
38
- self.class.attributes.each do |name, attr|
39
- value = attr.fetch(object, name)
40
- attr.validate!(
41
- value,
42
- coerced: attr.coerce(value),
43
- path: "#{path}.#{name}"
44
- )
45
- end
46
- end
47
-
48
- def coerce(object)
49
- object
50
- end
51
-
52
35
  class << self
53
36
  def call(object = nil, ...)
54
37
  new(object).call(...)
@@ -1,3 +1,3 @@
1
1
  module RiceBubble
2
- VERSION = '0.1.2'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
data/lib/rice_bubble.rb CHANGED
@@ -18,6 +18,11 @@ require_relative 'rice_bubble/attributes/time'
18
18
  require_relative 'rice_bubble/serializer'
19
19
 
20
20
  module RiceBubble
21
- class ValidationError < StandardError; end
22
- # Your code goes here...
21
+ class ValidationError < StandardError
22
+ attr_reader :value, :path, :attribute
23
+
24
+ def initialize(value:, path:, attribute:)
25
+ super("#{path} expected #{attribute.description} but received #{value.inspect}")
26
+ end
27
+ end
23
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rice_bubble
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Powell
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-22 00:00:00.000000000 Z
11
+ date: 2023-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake