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 +4 -4
- data/.rubocop.yml +1 -1
- data/Gemfile.lock +1 -1
- data/lib/rice_bubble/attributes/any.rb +6 -11
- data/lib/rice_bubble/attributes/array.rb +3 -11
- data/lib/rice_bubble/attributes/base.rb +14 -15
- data/lib/rice_bubble/attributes/boolean.rb +0 -4
- data/lib/rice_bubble/attributes/date.rb +4 -6
- data/lib/rice_bubble/attributes/datetime.rb +9 -16
- data/lib/rice_bubble/attributes/integer.rb +12 -8
- data/lib/rice_bubble/attributes/number.rb +5 -1
- data/lib/rice_bubble/attributes/object.rb +4 -9
- data/lib/rice_bubble/attributes/optional.rb +1 -5
- data/lib/rice_bubble/attributes/serialized.rb +3 -3
- data/lib/rice_bubble/attributes/string.rb +9 -9
- data/lib/rice_bubble/serializer.rb +1 -18
- data/lib/rice_bubble/version.rb +1 -1
- data/lib/rice_bubble.rb +7 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cbf4c6ade525140da24d50b1f12bf1a0d6bd0d8bd5e5b0b314204e8a086e04f
|
4
|
+
data.tar.gz: 2bb3ea6274dcb3859a7d56129554454dd888a4354f5b9500a1fbde8606e7e122
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26a31683aec0406224411ef415cfe70ce1d497223fd9c0e209c8835f1003e2abf33b8cad26a4cd65a521c6dc5726386a0887d6041d4b94065e6204ccb3a21394
|
7
|
+
data.tar.gz: 528efe018c746fcd2b24bb88267b7804bfa0195a6034acf2b5f81405a70857bbd3d2ef02a8c4d46b7567a6e8662e85d52ce4bfdb9630e533d6161431d915efdd
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -12,22 +12,17 @@ module RiceBubble
|
|
12
12
|
!which(value).nil?
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
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
|
20
|
-
|
21
|
-
members.
|
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?(
|
19
|
-
|
18
|
+
def valid?(value)
|
19
|
+
valid_types.any? { |t| value.is_a?(t) }
|
20
20
|
end
|
21
21
|
|
22
|
-
def
|
23
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
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,14 +1,12 @@
|
|
1
|
-
require 'date'
|
2
|
-
|
3
1
|
module RiceBubble
|
4
2
|
class Attributes
|
5
3
|
class Date < Base
|
6
|
-
def
|
7
|
-
value.
|
4
|
+
def call(value, path: '')
|
5
|
+
super(value.to_date, path:)
|
8
6
|
end
|
9
7
|
|
10
|
-
def
|
11
|
-
|
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
|
5
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
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
|
7
|
-
|
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
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
@@ -16,17 +16,12 @@ module RiceBubble
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
20
|
-
children.
|
21
|
-
|
22
|
-
|
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?(
|
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
|
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
|
16
|
-
serializer.
|
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
|
14
|
-
|
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
|
21
|
-
super
|
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
|
25
|
-
|
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(...)
|
data/lib/rice_bubble/version.rb
CHANGED
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
|
22
|
-
|
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.
|
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-
|
11
|
+
date: 2023-05-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|