dry-types 0.7.2 → 0.8.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -1
- data/Gemfile +1 -1
- data/dry-types.gemspec +2 -1
- data/lib/dry/types/array/member.rb +10 -4
- data/lib/dry/types/builder.rb +1 -1
- data/lib/dry/types/constrained.rb +1 -0
- data/lib/dry/types/constraints.rb +2 -10
- data/lib/dry/types/decorator.rb +17 -5
- data/lib/dry/types/default.rb +13 -2
- data/lib/dry/types/definition.rb +8 -0
- data/lib/dry/types/enum.rb +1 -0
- data/lib/dry/types/errors.rb +2 -1
- data/lib/dry/types/form.rb +2 -2
- data/lib/dry/types/hash.rb +5 -1
- data/lib/dry/types/hash/schema.rb +44 -26
- data/lib/dry/types/hashify.rb +12 -0
- data/lib/dry/types/maybe.rb +9 -0
- data/lib/dry/types/options.rb +1 -1
- data/lib/dry/types/safe.rb +5 -7
- data/lib/dry/types/struct.rb +7 -74
- data/lib/dry/types/struct/class_interface.rb +107 -0
- data/lib/dry/types/sum.rb +8 -0
- data/lib/dry/types/value.rb +3 -1
- data/lib/dry/types/version.rb +1 -1
- metadata +24 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9622054be99e8e44c40fe7cb054f81df88904d69
|
4
|
+
data.tar.gz: ea4110e3046187010e0b1c70f178ef90e50cbf37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02330a45f810e8a15f1dc47c2778360cede0a686136bce6d39f9f8b726d654c143b0d1546f36e9143e2cf539c0768ff3be3588e9e6e42568b5067eb96a9e909c
|
7
|
+
data.tar.gz: 193d63f9c8acbc4a266cbaf9ccfac6d3aba6cfcd9de25323d040bfb5c2a325273cb98890787fe2b38fe9faa8ebb54371fd58f875fb2de814d18acaa7a0c2bbbb
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
# v0.8.0 2016-07-01
|
2
|
+
|
3
|
+
## Added
|
4
|
+
|
5
|
+
* `Struct` now implements `Type` interface so ie `SomeStruct | String` works now (flash-gordon)
|
6
|
+
* `:weak` Hash constructor which can partially coerce a hash even when it includes invalid values (solnic)
|
7
|
+
* Types include `Dry::Equalizer` now (flash-gordon)
|
8
|
+
|
9
|
+
## Fixed
|
10
|
+
|
11
|
+
* `Struct#to_hash` descends into arrays too (nepalez)
|
12
|
+
* `Default#with` works now (flash-gordon)
|
13
|
+
|
14
|
+
## Changed
|
15
|
+
|
16
|
+
* `:symbolized` hash schema is now based on `:weak` schema (solnic)
|
17
|
+
* `Struct::Value` instances are now **deeply frozen** via ice_nine (backus)
|
18
|
+
|
19
|
+
[Compare v0.7.2...v0.8.0](https://github.com/dryrb/dry-types/compare/v0.7.2...v0.8.0)
|
20
|
+
|
1
21
|
# v0.7.2 2016-05-11
|
2
22
|
|
3
23
|
## Fixed
|
@@ -6,6 +26,7 @@
|
|
6
26
|
- Creating an empty schema with input processor no longer fails (lasseebert)
|
7
27
|
|
8
28
|
## Changes
|
29
|
+
|
9
30
|
- Allow multiple calls to meta (solnic)
|
10
31
|
- Allow capitalised versions of true and false values for boolean coercions (nil0bject)
|
11
32
|
- Replace kleisli with dry-monads (flash-gordon)
|
@@ -14,7 +35,7 @@
|
|
14
35
|
- Coerce empty strings in form posts to blank arrays and hashes (timriley)
|
15
36
|
- update to use dry-logic v0.2.3 (fran-worley)
|
16
37
|
|
17
|
-
[Compare v0.7.
|
38
|
+
[Compare v0.7.1...v0.7.2](https://github.com/dryrb/dry-types/compare/v0.7.1...v0.7.2)
|
18
39
|
|
19
40
|
# v0.7.1 2016-04-06
|
20
41
|
|
data/Gemfile
CHANGED
data/dry-types.gemspec
CHANGED
@@ -31,9 +31,10 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_runtime_dependency 'dry-container', '~> 0.3'
|
32
32
|
spec.add_runtime_dependency 'dry-equalizer', '~> 0.2'
|
33
33
|
spec.add_runtime_dependency 'dry-configurable', '~> 0.1'
|
34
|
-
spec.add_runtime_dependency 'dry-logic', '~> 0.
|
34
|
+
spec.add_runtime_dependency 'dry-logic', '~> 0.3', '>= 0.3.0'
|
35
35
|
spec.add_runtime_dependency 'inflecto', '~> 0.0.0', '>= 0.0.2'
|
36
36
|
spec.add_runtime_dependency 'dry-monads', '>= 0.0.1'
|
37
|
+
spec.add_runtime_dependency 'ice_nine', '~> 0.11'
|
37
38
|
|
38
39
|
spec.add_development_dependency "bundler", "~> 1.6"
|
39
40
|
spec.add_development_dependency "rake", "~> 11.0"
|
@@ -15,12 +15,18 @@ module Dry
|
|
15
15
|
alias_method :[], :call
|
16
16
|
|
17
17
|
def try(input, &block)
|
18
|
-
|
18
|
+
if input.is_a?(::Array)
|
19
|
+
result = call(input, :try)
|
20
|
+
output = result.map(&:input)
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
+
if result.all?(&:success?)
|
23
|
+
success(output)
|
24
|
+
else
|
25
|
+
failure = failure(output, result.select(&:failure?))
|
26
|
+
block ? yield(failure) : failure
|
27
|
+
end
|
22
28
|
else
|
23
|
-
failure = failure(input,
|
29
|
+
failure = failure(input, "#{input} is not an array")
|
24
30
|
block ? yield(failure) : failure
|
25
31
|
end
|
26
32
|
end
|
data/lib/dry/types/builder.rb
CHANGED
@@ -26,7 +26,7 @@ module Dry
|
|
26
26
|
value = input == Undefined ? block : input
|
27
27
|
|
28
28
|
if value.is_a?(Proc) || valid?(value)
|
29
|
-
Default[value].new(self, value
|
29
|
+
Default[value].new(self, value)
|
30
30
|
else
|
31
31
|
raise ConstraintError, "default value #{value.inspect} violates constraints"
|
32
32
|
end
|
@@ -3,22 +3,14 @@ require 'dry/logic/predicates'
|
|
3
3
|
|
4
4
|
module Dry
|
5
5
|
module Types
|
6
|
-
module Predicates
|
7
|
-
include Logic::Predicates
|
8
|
-
|
9
|
-
predicate(:type?) do |type, value|
|
10
|
-
value.kind_of?(type)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
6
|
def self.Rule(options)
|
15
7
|
rule_compiler.(
|
16
|
-
options.map { |key, val| [:val, [:
|
8
|
+
options.map { |key, val| [:val, Logic::Predicates[:"#{key}?"].curry(val).to_ast] }
|
17
9
|
).reduce(:and)
|
18
10
|
end
|
19
11
|
|
20
12
|
def self.rule_compiler
|
21
|
-
@rule_compiler ||= Logic::RuleCompiler.new(
|
13
|
+
@rule_compiler ||= Logic::RuleCompiler.new(Logic::Predicates)
|
22
14
|
end
|
23
15
|
end
|
24
16
|
end
|
data/lib/dry/types/decorator.rb
CHANGED
@@ -1,25 +1,37 @@
|
|
1
|
+
require 'dry/types/options'
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
module Types
|
3
5
|
module Decorator
|
4
|
-
|
6
|
+
include Options
|
7
|
+
|
8
|
+
attr_reader :type
|
5
9
|
|
6
|
-
def initialize(type,
|
10
|
+
def initialize(type, *)
|
11
|
+
super
|
7
12
|
@type = type
|
8
|
-
@options = options
|
9
13
|
end
|
10
14
|
|
11
15
|
def constructor
|
12
16
|
type.constructor
|
13
17
|
end
|
14
18
|
|
15
|
-
def
|
16
|
-
|
19
|
+
def try(input, &block)
|
20
|
+
type.try(input, &block)
|
17
21
|
end
|
18
22
|
|
19
23
|
def valid?(value)
|
20
24
|
type.valid?(value)
|
21
25
|
end
|
22
26
|
|
27
|
+
def default?
|
28
|
+
type.default?
|
29
|
+
end
|
30
|
+
|
31
|
+
def maybe?
|
32
|
+
type.maybe?
|
33
|
+
end
|
34
|
+
|
23
35
|
def respond_to_missing?(meth, include_private = false)
|
24
36
|
super || type.respond_to?(meth)
|
25
37
|
end
|
data/lib/dry/types/default.rb
CHANGED
@@ -3,10 +3,13 @@ require 'dry/types/decorator'
|
|
3
3
|
module Dry
|
4
4
|
module Types
|
5
5
|
class Default
|
6
|
+
include Dry::Equalizer(:type, :options, :value)
|
6
7
|
include Decorator
|
7
8
|
include Builder
|
8
9
|
|
9
10
|
class Callable < Default
|
11
|
+
include Dry::Equalizer(:type, :options)
|
12
|
+
|
10
13
|
def evaluate
|
11
14
|
value.call
|
12
15
|
end
|
@@ -24,15 +27,23 @@ module Dry
|
|
24
27
|
end
|
25
28
|
end
|
26
29
|
|
27
|
-
def initialize(type,
|
30
|
+
def initialize(type, value, *)
|
28
31
|
super
|
29
|
-
@value =
|
32
|
+
@value = value
|
30
33
|
end
|
31
34
|
|
32
35
|
def constrained(*args)
|
33
36
|
type.constrained(*args).default(value)
|
34
37
|
end
|
35
38
|
|
39
|
+
def default?
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
def try(input)
|
44
|
+
success(call(input))
|
45
|
+
end
|
46
|
+
|
36
47
|
def call(input)
|
37
48
|
if input.nil?
|
38
49
|
evaluate
|
data/lib/dry/types/definition.rb
CHANGED
data/lib/dry/types/enum.rb
CHANGED
data/lib/dry/types/errors.rb
CHANGED
@@ -43,7 +43,8 @@ module Dry
|
|
43
43
|
def failure_message
|
44
44
|
if result.respond_to?(:rule)
|
45
45
|
rule = result.rule
|
46
|
-
|
46
|
+
args = rule.predicate.args - [rule.predicate.args.last]
|
47
|
+
"#{rule.predicate.id}(#{args.map(&:inspect).join(', ')}) failed"
|
47
48
|
else
|
48
49
|
result.inspect
|
49
50
|
end
|
data/lib/dry/types/form.rb
CHANGED
@@ -43,11 +43,11 @@ module Dry
|
|
43
43
|
end
|
44
44
|
|
45
45
|
register('form.array') do
|
46
|
-
self['array'].
|
46
|
+
self['array'].constructor(Coercions::Form.method(:to_ary)).safe
|
47
47
|
end
|
48
48
|
|
49
49
|
register('form.hash') do
|
50
|
-
self['hash'].
|
50
|
+
self['hash'].constructor(Coercions::Form.method(:to_hash)).safe
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
data/lib/dry/types/hash.rb
CHANGED
@@ -3,7 +3,7 @@ require 'dry/types/hash/schema'
|
|
3
3
|
module Dry
|
4
4
|
module Types
|
5
5
|
class Hash < Definition
|
6
|
-
def schema(type_map, klass =
|
6
|
+
def schema(type_map, klass = Schema)
|
7
7
|
member_types = type_map.each_with_object({}) { |(name, type), result|
|
8
8
|
result[name] =
|
9
9
|
case type
|
@@ -15,6 +15,10 @@ module Dry
|
|
15
15
|
klass.new(primitive, options.merge(member_types: member_types))
|
16
16
|
end
|
17
17
|
|
18
|
+
def weak(type_map)
|
19
|
+
schema(type_map, Weak)
|
20
|
+
end
|
21
|
+
|
18
22
|
def strict(type_map)
|
19
23
|
schema(type_map, Strict)
|
20
24
|
end
|
@@ -9,13 +9,25 @@ module Dry
|
|
9
9
|
super
|
10
10
|
end
|
11
11
|
|
12
|
+
def call(hash, meth = :call)
|
13
|
+
member_types.each_with_object({}) do |(key, type), result|
|
14
|
+
if hash.key?(key)
|
15
|
+
result[key] = type.__send__(meth, hash[key])
|
16
|
+
else
|
17
|
+
resolve_missing_value(result, key, type)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
alias_method :[], :call
|
22
|
+
|
12
23
|
def try(hash, &block)
|
13
24
|
result = call(hash, :try)
|
25
|
+
output = result.each_with_object({}) { |(key, res), h| h[key] = res.input }
|
14
26
|
|
15
27
|
if result.values.all?(&:success?)
|
16
|
-
success(
|
28
|
+
success(output)
|
17
29
|
else
|
18
|
-
failure = failure(
|
30
|
+
failure = failure(output, result)
|
19
31
|
block ? yield(failure) : failure
|
20
32
|
end
|
21
33
|
end
|
@@ -23,28 +35,50 @@ module Dry
|
|
23
35
|
private
|
24
36
|
|
25
37
|
def resolve_missing_value(result, key, type)
|
26
|
-
if type.
|
38
|
+
if type.default?
|
27
39
|
result[key] = type.evaluate
|
28
|
-
elsif type.
|
40
|
+
elsif type.maybe?
|
29
41
|
result[key] = type[nil]
|
30
42
|
end
|
31
43
|
end
|
32
44
|
end
|
33
45
|
|
34
|
-
class
|
46
|
+
class Strict < Schema
|
35
47
|
def call(hash, meth = :call)
|
36
48
|
member_types.each_with_object({}) do |(key, type), result|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
49
|
+
begin
|
50
|
+
value = hash.fetch(key)
|
51
|
+
result[key] = type.__send__(meth, value)
|
52
|
+
rescue TypeError
|
53
|
+
raise SchemaError.new(key, value)
|
54
|
+
rescue KeyError
|
55
|
+
raise SchemaKeyError.new(key)
|
41
56
|
end
|
42
57
|
end
|
43
58
|
end
|
44
59
|
alias_method :[], :call
|
45
60
|
end
|
46
61
|
|
47
|
-
class
|
62
|
+
class Weak < Schema
|
63
|
+
def self.new(primitive, options = {})
|
64
|
+
member_types = options.
|
65
|
+
fetch(:member_types, {}).
|
66
|
+
each_with_object({}) { |(k, t), res| res[k] = t.safe }
|
67
|
+
|
68
|
+
super(primitive, options.merge(member_types: member_types))
|
69
|
+
end
|
70
|
+
|
71
|
+
def try(hash, &block)
|
72
|
+
if hash.is_a?(::Hash)
|
73
|
+
super
|
74
|
+
else
|
75
|
+
result = failure(hash, "#{hash} must be a hash")
|
76
|
+
block ? yield(result) : result
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Symbolized < Weak
|
48
82
|
def call(hash, meth = :call)
|
49
83
|
member_types.each_with_object({}) do |(key, type), result|
|
50
84
|
if hash.key?(key)
|
@@ -62,22 +96,6 @@ module Dry
|
|
62
96
|
end
|
63
97
|
alias_method :[], :call
|
64
98
|
end
|
65
|
-
|
66
|
-
class Strict < Schema
|
67
|
-
def call(hash, meth = :call)
|
68
|
-
member_types.each_with_object({}) do |(key, type), result|
|
69
|
-
begin
|
70
|
-
value = hash.fetch(key)
|
71
|
-
result[key] = type.__send__(meth, value)
|
72
|
-
rescue TypeError
|
73
|
-
raise SchemaError.new(key, value)
|
74
|
-
rescue KeyError
|
75
|
-
raise SchemaKeyError.new(key)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
alias_method :[], :call
|
80
|
-
end
|
81
99
|
end
|
82
100
|
end
|
83
101
|
end
|
data/lib/dry/types/maybe.rb
CHANGED
@@ -4,6 +4,7 @@ require 'dry/types/decorator'
|
|
4
4
|
module Dry
|
5
5
|
module Types
|
6
6
|
class Maybe
|
7
|
+
include Dry::Equalizer(:type, :options)
|
7
8
|
include Decorator
|
8
9
|
include Builder
|
9
10
|
include Dry::Monads::Maybe::Mixin
|
@@ -13,6 +14,14 @@ module Dry
|
|
13
14
|
end
|
14
15
|
alias_method :[], :call
|
15
16
|
|
17
|
+
def try(input)
|
18
|
+
Result::Success.new(Maybe(type[input]))
|
19
|
+
end
|
20
|
+
|
21
|
+
def maybe?
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
16
25
|
def default(value)
|
17
26
|
if value.nil?
|
18
27
|
raise ArgumentError, "nil cannot be used as a default of a maybe type"
|
data/lib/dry/types/options.rb
CHANGED
data/lib/dry/types/safe.rb
CHANGED
@@ -3,22 +3,20 @@ require 'dry/types/decorator'
|
|
3
3
|
module Dry
|
4
4
|
module Types
|
5
5
|
class Safe
|
6
|
+
include Dry::Equalizer(:type, :options)
|
6
7
|
include Decorator
|
7
8
|
include Builder
|
8
9
|
|
9
10
|
def call(input)
|
10
|
-
|
11
|
-
type[input]
|
12
|
-
else
|
13
|
-
input
|
14
|
-
end
|
15
|
-
rescue TypeError
|
16
|
-
input
|
11
|
+
try(input).input
|
17
12
|
end
|
18
13
|
alias_method :[], :call
|
19
14
|
|
20
15
|
def try(input, &block)
|
21
16
|
type.try(input, &block)
|
17
|
+
rescue TypeError, ArgumentError => e
|
18
|
+
result = failure(input, e.message)
|
19
|
+
block ? yield(result) : result
|
22
20
|
end
|
23
21
|
|
24
22
|
private
|
data/lib/dry/types/struct.rb
CHANGED
@@ -1,76 +1,10 @@
|
|
1
|
+
require_relative 'hashify'
|
2
|
+
require 'dry/types/struct/class_interface'
|
3
|
+
|
1
4
|
module Dry
|
2
5
|
module Types
|
3
6
|
class Struct
|
4
|
-
|
5
|
-
attr_reader :constructor
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.inherited(klass)
|
9
|
-
super
|
10
|
-
|
11
|
-
klass.instance_variable_set('@equalizer', Equalizer.new(*schema.keys))
|
12
|
-
klass.instance_variable_set('@constructor_type', constructor_type)
|
13
|
-
klass.send(:include, klass.equalizer)
|
14
|
-
|
15
|
-
unless klass == Value
|
16
|
-
klass.instance_variable_set('@constructor', Types['coercible.hash'])
|
17
|
-
Types.register_class(klass)
|
18
|
-
end
|
19
|
-
|
20
|
-
klass.attributes({}) unless equal?(Struct)
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.equalizer
|
24
|
-
@equalizer
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.attribute(name, type)
|
28
|
-
attributes(name => type)
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.attributes(new_schema)
|
32
|
-
check_schema_duplication(new_schema)
|
33
|
-
|
34
|
-
prev_schema = schema
|
35
|
-
|
36
|
-
@schema = prev_schema.merge(new_schema)
|
37
|
-
@constructor = Types['coercible.hash'].public_send(constructor_type, schema)
|
38
|
-
|
39
|
-
attr_reader(*new_schema.keys)
|
40
|
-
equalizer.instance_variable_get('@keys').concat(new_schema.keys)
|
41
|
-
|
42
|
-
self
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.check_schema_duplication(new_schema)
|
46
|
-
shared_keys = new_schema.keys & schema.keys
|
47
|
-
|
48
|
-
fail RepeatedAttributeError, shared_keys.first if shared_keys.any?
|
49
|
-
end
|
50
|
-
private_class_method :check_schema_duplication
|
51
|
-
|
52
|
-
def self.constructor_type(type = nil)
|
53
|
-
if type
|
54
|
-
@constructor_type = type
|
55
|
-
else
|
56
|
-
@constructor_type || :strict
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.schema
|
61
|
-
super_schema = superclass.respond_to?(:schema) ? superclass.schema : {}
|
62
|
-
super_schema.merge(@schema || {})
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.new(attributes = {})
|
66
|
-
if attributes.instance_of?(self)
|
67
|
-
attributes
|
68
|
-
else
|
69
|
-
super(constructor[attributes])
|
70
|
-
end
|
71
|
-
rescue SchemaError, SchemaKeyError => error
|
72
|
-
raise StructError, "[#{self}.new] #{error}"
|
73
|
-
end
|
7
|
+
extend ClassInterface
|
74
8
|
|
75
9
|
def initialize(attributes)
|
76
10
|
attributes.each { |key, value| instance_variable_set("@#{key}", value) }
|
@@ -81,10 +15,9 @@ module Dry
|
|
81
15
|
end
|
82
16
|
|
83
17
|
def to_hash
|
84
|
-
self.class.schema.keys.each_with_object({})
|
85
|
-
|
86
|
-
|
87
|
-
}
|
18
|
+
self.class.schema.keys.each_with_object({}) do |key, result|
|
19
|
+
result[key] = Hashify[self[key]]
|
20
|
+
end
|
88
21
|
end
|
89
22
|
alias_method :to_h, :to_hash
|
90
23
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Dry
|
2
|
+
module Types
|
3
|
+
class Struct
|
4
|
+
module ClassInterface
|
5
|
+
include Builder
|
6
|
+
|
7
|
+
attr_accessor :constructor
|
8
|
+
|
9
|
+
attr_accessor :equalizer
|
10
|
+
|
11
|
+
attr_writer :constructor_type
|
12
|
+
|
13
|
+
protected :constructor=, :equalizer=, :constructor_type=
|
14
|
+
|
15
|
+
def inherited(klass)
|
16
|
+
super
|
17
|
+
|
18
|
+
klass.equalizer = Equalizer.new(*schema.keys)
|
19
|
+
klass.constructor_type = constructor_type
|
20
|
+
klass.send(:include, klass.equalizer)
|
21
|
+
|
22
|
+
unless klass == Value
|
23
|
+
klass.constructor = Types['coercible.hash']
|
24
|
+
Types.register(Types.identifier(klass), klass)
|
25
|
+
end
|
26
|
+
|
27
|
+
klass.attributes({}) unless equal?(Struct)
|
28
|
+
end
|
29
|
+
|
30
|
+
def attribute(name, type)
|
31
|
+
attributes(name => type)
|
32
|
+
end
|
33
|
+
|
34
|
+
def attributes(new_schema)
|
35
|
+
check_schema_duplication(new_schema)
|
36
|
+
|
37
|
+
prev_schema = schema
|
38
|
+
|
39
|
+
@schema = prev_schema.merge(new_schema)
|
40
|
+
@constructor = Types['coercible.hash'].public_send(constructor_type, schema)
|
41
|
+
|
42
|
+
attr_reader(*new_schema.keys)
|
43
|
+
equalizer.instance_variable_get('@keys').concat(new_schema.keys)
|
44
|
+
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def check_schema_duplication(new_schema)
|
49
|
+
shared_keys = new_schema.keys & schema.keys
|
50
|
+
|
51
|
+
fail RepeatedAttributeError, shared_keys.first if shared_keys.any?
|
52
|
+
end
|
53
|
+
private :check_schema_duplication
|
54
|
+
|
55
|
+
def constructor_type(type = nil)
|
56
|
+
if type
|
57
|
+
@constructor_type = type
|
58
|
+
else
|
59
|
+
@constructor_type || :strict
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def schema
|
64
|
+
super_schema = superclass.respond_to?(:schema) ? superclass.schema : {}
|
65
|
+
super_schema.merge(@schema || {})
|
66
|
+
end
|
67
|
+
|
68
|
+
def new(attributes = default_attributes)
|
69
|
+
if attributes.instance_of?(self)
|
70
|
+
attributes
|
71
|
+
else
|
72
|
+
super(constructor[attributes])
|
73
|
+
end
|
74
|
+
rescue SchemaError, SchemaKeyError => error
|
75
|
+
raise StructError, "[#{self}.new] #{error}"
|
76
|
+
end
|
77
|
+
alias_method :call, :new
|
78
|
+
alias_method :[], :new
|
79
|
+
|
80
|
+
def default_attributes
|
81
|
+
schema.each_with_object({}) { |(name, type), result|
|
82
|
+
result[name] = type.default? ? type.evaluate : type[nil]
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def try(input)
|
87
|
+
Result::Success.new(self[input])
|
88
|
+
rescue StructError => e
|
89
|
+
failure = Result::Failure.new(input, e.message)
|
90
|
+
block_given? ? yield(failure) : failure
|
91
|
+
end
|
92
|
+
|
93
|
+
def maybe?
|
94
|
+
false
|
95
|
+
end
|
96
|
+
|
97
|
+
def default?
|
98
|
+
false
|
99
|
+
end
|
100
|
+
|
101
|
+
def valid?(value)
|
102
|
+
self === value
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/dry/types/sum.rb
CHANGED
data/lib/dry/types/value.rb
CHANGED
data/lib/dry/types/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-types
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -72,20 +72,20 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0.
|
75
|
+
version: '0.3'
|
76
76
|
- - ">="
|
77
77
|
- !ruby/object:Gem::Version
|
78
|
-
version: 0.
|
78
|
+
version: 0.3.0
|
79
79
|
type: :runtime
|
80
80
|
prerelease: false
|
81
81
|
version_requirements: !ruby/object:Gem::Requirement
|
82
82
|
requirements:
|
83
83
|
- - "~>"
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version: '0.
|
85
|
+
version: '0.3'
|
86
86
|
- - ">="
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: 0.
|
88
|
+
version: 0.3.0
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: inflecto
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,6 +120,20 @@ dependencies:
|
|
120
120
|
- - ">="
|
121
121
|
- !ruby/object:Gem::Version
|
122
122
|
version: 0.0.1
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: ice_nine
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0.11'
|
130
|
+
type: :runtime
|
131
|
+
prerelease: false
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - "~>"
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0.11'
|
123
137
|
- !ruby/object:Gem::Dependency
|
124
138
|
name: bundler
|
125
139
|
requirement: !ruby/object:Gem::Requirement
|
@@ -206,12 +220,14 @@ files:
|
|
206
220
|
- lib/dry/types/form.rb
|
207
221
|
- lib/dry/types/hash.rb
|
208
222
|
- lib/dry/types/hash/schema.rb
|
223
|
+
- lib/dry/types/hashify.rb
|
209
224
|
- lib/dry/types/json.rb
|
210
225
|
- lib/dry/types/maybe.rb
|
211
226
|
- lib/dry/types/options.rb
|
212
227
|
- lib/dry/types/result.rb
|
213
228
|
- lib/dry/types/safe.rb
|
214
229
|
- lib/dry/types/struct.rb
|
230
|
+
- lib/dry/types/struct/class_interface.rb
|
215
231
|
- lib/dry/types/sum.rb
|
216
232
|
- lib/dry/types/value.rb
|
217
233
|
- lib/dry/types/version.rb
|
@@ -236,9 +252,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
236
252
|
version: '0'
|
237
253
|
requirements: []
|
238
254
|
rubyforge_project:
|
239
|
-
rubygems_version: 2.
|
255
|
+
rubygems_version: 2.5.1
|
240
256
|
signing_key:
|
241
257
|
specification_version: 4
|
242
258
|
summary: Type system for Ruby supporting coercions, constraints and complex types
|
243
259
|
like structs, value objects, enums etc.
|
244
260
|
test_files: []
|
261
|
+
has_rdoc:
|