dry-types 0.9.2 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +10 -6
- data/.yardopts +5 -0
- data/CHANGELOG.md +9 -1
- data/Gemfile +4 -1
- data/Rakefile +4 -0
- data/dry-types.gemspec +2 -1
- data/lib/dry/types.rb +25 -0
- data/lib/dry/types/array.rb +2 -0
- data/lib/dry/types/array/member.rb +16 -2
- data/lib/dry/types/builder.rb +17 -2
- data/lib/dry/types/coercions.rb +14 -2
- data/lib/dry/types/coercions/form.rb +18 -0
- data/lib/dry/types/coercions/json.rb +2 -0
- data/lib/dry/types/constrained.rb +21 -0
- data/lib/dry/types/constrained/coercible.rb +5 -0
- data/lib/dry/types/constraints.rb +3 -0
- data/lib/dry/types/constructor.rb +28 -0
- data/lib/dry/types/decorator.rb +19 -0
- data/lib/dry/types/default.rb +14 -0
- data/lib/dry/types/definition.rb +31 -4
- data/lib/dry/types/enum.rb +10 -1
- data/lib/dry/types/errors.rb +14 -2
- data/lib/dry/types/extensions/maybe.rb +19 -2
- data/lib/dry/types/hash.rb +18 -0
- data/lib/dry/types/hash/schema.rb +69 -0
- data/lib/dry/types/options.rb +6 -0
- data/lib/dry/types/result.rb +10 -0
- data/lib/dry/types/safe.rb +9 -0
- data/lib/dry/types/sum.rb +20 -0
- data/lib/dry/types/version.rb +1 -1
- metadata +23 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5aba3a0d92022b867e134a072196692b4f0d837
|
4
|
+
data.tar.gz: d2a5c7e8b8c489ec5b507a92f92be026e7337d78
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5c1a092cf9a157bdcbecc6aec42fa6731ab1e9a9067c81bb7e109a7516393128c0c183ceb4d589258bea87631da55735e38a4b44860f005ea2230b43985e406
|
7
|
+
data.tar.gz: 706d91386ba41582d7eb927237790bf51c0790fc909b248b9a70c851070fb0f49e897e54098f51891fcd5afdd2ee7311fffb6deff7e8b9061b1b6b2135802743
|
data/.travis.yml
CHANGED
@@ -1,21 +1,25 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
2
|
+
dist: trusty
|
3
|
+
sudo: required
|
3
4
|
cache: bundler
|
4
5
|
bundler_args: --without benchmarks tools
|
6
|
+
after_success:
|
7
|
+
- '[ "$TRAVIS_RUBY_VERSION" = "2.3.1" ] && [ "$TRAVIS_BRANCH" = "master" ] && bundle exec codeclimate-test-reporter'
|
5
8
|
script:
|
6
9
|
- bundle exec rake
|
7
10
|
rvm:
|
8
|
-
- 2.1
|
9
|
-
- 2.2
|
10
|
-
- 2.3
|
11
|
+
- 2.1
|
12
|
+
- 2.2
|
13
|
+
- 2.3
|
11
14
|
- jruby-9.1.5.0
|
12
|
-
- rbx-3
|
15
|
+
- rbx-3
|
13
16
|
env:
|
14
17
|
global:
|
18
|
+
- COVERAGE=true
|
15
19
|
- JRUBY_OPTS='--dev -J-Xmx1024M'
|
16
20
|
matrix:
|
17
21
|
allow_failures:
|
18
|
-
- rvm: rbx-3
|
22
|
+
- rvm: rbx-3
|
19
23
|
notifications:
|
20
24
|
email: false
|
21
25
|
webhooks:
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,12 @@
|
|
1
|
-
# v0.9.
|
1
|
+
# v0.9.3 2016-12-03
|
2
|
+
|
3
|
+
## Fixed
|
4
|
+
|
5
|
+
* Updated to dry-core >= 0.2.1 (ruby warnings are gone) (flash-gordon)
|
6
|
+
|
7
|
+
[Compare v0.9.2...v0.9.3](https://github.com/dryrb/dry-types/compare/v0.9.2...v0.9.3)
|
8
|
+
|
9
|
+
# v0.9.2 2016-11-13
|
2
10
|
|
3
11
|
## Added
|
4
12
|
|
data/Gemfile
CHANGED
@@ -3,7 +3,10 @@ source 'https://rubygems.org'
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
group :test do
|
6
|
-
|
6
|
+
platform :mri do
|
7
|
+
gem "codeclimate-test-reporter", require: false
|
8
|
+
gem 'simplecov', require: false
|
9
|
+
end
|
7
10
|
end
|
8
11
|
|
9
12
|
group :tools do
|
data/Rakefile
CHANGED
data/dry-types.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.required_ruby_version = ">= 2.1.0"
|
30
30
|
|
31
31
|
spec.add_runtime_dependency 'concurrent-ruby', '~> 1.0'
|
32
|
-
spec.add_runtime_dependency 'dry-core', '~> 0.2'
|
32
|
+
spec.add_runtime_dependency 'dry-core', '~> 0.2', '>= 0.2.1'
|
33
33
|
spec.add_runtime_dependency 'dry-container', '~> 0.3'
|
34
34
|
spec.add_runtime_dependency 'dry-equalizer', '~> 0.2'
|
35
35
|
spec.add_runtime_dependency 'dry-configurable', '~> 0.1'
|
@@ -40,4 +40,5 @@ Gem::Specification.new do |spec|
|
|
40
40
|
spec.add_development_dependency "rake", "~> 11.0"
|
41
41
|
spec.add_development_dependency "rspec", "~> 3.3"
|
42
42
|
spec.add_development_dependency 'dry-monads', '~> 0.2'
|
43
|
+
spec.add_development_dependency 'yard', '~> 0.9.5'
|
43
44
|
end
|
data/lib/dry/types.rb
CHANGED
@@ -8,6 +8,7 @@ require 'concurrent'
|
|
8
8
|
require 'dry-container'
|
9
9
|
require 'dry-equalizer'
|
10
10
|
require 'dry/core/extensions'
|
11
|
+
require 'dry/core/constants'
|
11
12
|
|
12
13
|
require 'dry/types/version'
|
13
14
|
require 'dry/types/container'
|
@@ -20,17 +21,22 @@ module Dry
|
|
20
21
|
module Types
|
21
22
|
extend Dry::Configurable
|
22
23
|
extend Dry::Core::Extensions
|
24
|
+
include Dry::Core::Constants
|
23
25
|
|
26
|
+
# @!attribute [r] namespace
|
27
|
+
# @return [Container{String => Definition}]
|
24
28
|
setting :namespace, self
|
25
29
|
|
26
30
|
TYPE_SPEC_REGEX = %r[(.+)<(.+)>].freeze
|
27
31
|
|
32
|
+
# @return [Module]
|
28
33
|
def self.module
|
29
34
|
namespace = Module.new
|
30
35
|
define_constants(namespace, type_keys)
|
31
36
|
namespace
|
32
37
|
end
|
33
38
|
|
39
|
+
# @deprecated Include {Dry::Types.module} instead
|
34
40
|
def self.finalize
|
35
41
|
warn 'Dry::Types.finalize and configuring namespace is deprecated. Just'\
|
36
42
|
' do `include Dry::Types.module` in places where you want to have access'\
|
@@ -39,19 +45,30 @@ module Dry
|
|
39
45
|
define_constants(config.namespace, type_keys)
|
40
46
|
end
|
41
47
|
|
48
|
+
# @return [Container{String => Definition}]
|
42
49
|
def self.container
|
43
50
|
@container ||= Container.new
|
44
51
|
end
|
45
52
|
|
53
|
+
# @param [String] name
|
54
|
+
# @param [Definition] type
|
55
|
+
# @param [#call] block
|
56
|
+
# @return [Container{String => Definition}]
|
46
57
|
def self.register(name, type = nil, &block)
|
47
58
|
container.register(name, type || block.call)
|
48
59
|
end
|
49
60
|
|
61
|
+
# Registers given +klass+ in {#container} using +meth+ constructor
|
62
|
+
# @param [Class] klass
|
63
|
+
# @param [Symbol] meth
|
64
|
+
# @return [Container{String => Definition}]
|
50
65
|
def self.register_class(klass, meth = :new)
|
51
66
|
type = Definition.new(klass).constructor(klass.method(meth))
|
52
67
|
container.register(identifier(klass), type)
|
53
68
|
end
|
54
69
|
|
70
|
+
# @param [String] name
|
71
|
+
# @return [Definition]
|
55
72
|
def self.[](name)
|
56
73
|
type_map.fetch_or_store(name) do
|
57
74
|
case name
|
@@ -76,6 +93,9 @@ module Dry
|
|
76
93
|
end
|
77
94
|
end
|
78
95
|
|
96
|
+
# @param [Container{String => Definition}] namespace
|
97
|
+
# @param [<String>] identifiers
|
98
|
+
# @return [<Definition>]
|
79
99
|
def self.define_constants(namespace, identifiers)
|
80
100
|
names = identifiers.map do |id|
|
81
101
|
parts = id.split('.')
|
@@ -91,14 +111,19 @@ module Dry
|
|
91
111
|
end
|
92
112
|
end
|
93
113
|
|
114
|
+
# @param [#to_s] klass
|
115
|
+
# @return [String]
|
94
116
|
def self.identifier(klass)
|
95
117
|
Inflecto.underscore(klass).tr('/', '.')
|
96
118
|
end
|
97
119
|
|
120
|
+
# @return [Concurrent::Map]
|
98
121
|
def self.type_map
|
99
122
|
@type_map ||= Concurrent::Map.new
|
100
123
|
end
|
101
124
|
|
125
|
+
# List of type keys defined in {Dry::Types.container}
|
126
|
+
# @return [<String>]
|
102
127
|
def self.type_keys
|
103
128
|
container._container.keys
|
104
129
|
end
|
data/lib/dry/types/array.rb
CHANGED
@@ -2,22 +2,36 @@ module Dry
|
|
2
2
|
module Types
|
3
3
|
class Array < Definition
|
4
4
|
class Member < Array
|
5
|
+
# @return [Definition]
|
5
6
|
attr_reader :member
|
6
7
|
|
8
|
+
# @param [Class] primitive
|
9
|
+
# @param [Hash] options
|
10
|
+
# @option options [Definition] :member
|
7
11
|
def initialize(primitive, options = {})
|
8
12
|
@member = options.fetch(:member)
|
9
13
|
super
|
10
14
|
end
|
11
15
|
|
16
|
+
# @param [Object] input
|
17
|
+
# @param [Symbol] meth
|
18
|
+
# @return [Array]
|
12
19
|
def call(input, meth = :call)
|
13
20
|
input.map { |el| member.__send__(meth, el) }
|
14
21
|
end
|
15
22
|
alias_method :[], :call
|
16
23
|
|
17
|
-
|
18
|
-
|
24
|
+
# @param [Array, #all?] value
|
25
|
+
# @return [Boolean]
|
26
|
+
def valid?(value)
|
27
|
+
super && value.all? { |el| member.valid?(el) }
|
19
28
|
end
|
20
29
|
|
30
|
+
# @param [Array, Object] input
|
31
|
+
# @param [#call] block
|
32
|
+
# @yieldparam [Failure] failure
|
33
|
+
# @yieldreturn [Result]
|
34
|
+
# @return [Result]
|
21
35
|
def try(input, &block)
|
22
36
|
if input.is_a?(::Array)
|
23
37
|
result = call(input, :try)
|
data/lib/dry/types/builder.rb
CHANGED
@@ -1,27 +1,35 @@
|
|
1
|
-
require 'dry/core/constants'
|
2
|
-
|
3
1
|
module Dry
|
4
2
|
module Types
|
5
3
|
module Builder
|
6
4
|
include Dry::Core::Constants
|
7
5
|
|
6
|
+
# @return [Constrained]
|
8
7
|
def constrained_type
|
9
8
|
Constrained
|
10
9
|
end
|
11
10
|
|
11
|
+
# @param [Definition] other
|
12
|
+
# @return [Sum, Sum::Constrained]
|
12
13
|
def |(other)
|
13
14
|
klass = constrained? && other.constrained? ? Sum::Constrained : Sum
|
14
15
|
klass.new(self, other)
|
15
16
|
end
|
16
17
|
|
18
|
+
# @return [Sum]
|
17
19
|
def optional
|
18
20
|
Types['strict.nil'] | self
|
19
21
|
end
|
20
22
|
|
23
|
+
# @param [Hash] options constraining rule (see {Types.Rule})
|
24
|
+
# @return [Constrained]
|
21
25
|
def constrained(options)
|
22
26
|
constrained_type.new(self, rule: Types.Rule(options))
|
23
27
|
end
|
24
28
|
|
29
|
+
# @param [Object] input
|
30
|
+
# @param [#call] block
|
31
|
+
# @raise [ConstraintError]
|
32
|
+
# @return [Default]
|
25
33
|
def default(input = Undefined, &block)
|
26
34
|
value = input == Undefined ? block : input
|
27
35
|
|
@@ -32,14 +40,21 @@ module Dry
|
|
32
40
|
end
|
33
41
|
end
|
34
42
|
|
43
|
+
# @param [Array] values
|
44
|
+
# @return [Enum]
|
35
45
|
def enum(*values)
|
36
46
|
Enum.new(constrained(included_in: values), values: values)
|
37
47
|
end
|
38
48
|
|
49
|
+
# @return [Safe]
|
39
50
|
def safe
|
40
51
|
Safe.new(self)
|
41
52
|
end
|
42
53
|
|
54
|
+
# @param [#call] constructor
|
55
|
+
# @param [Hash] options
|
56
|
+
# @param [#call] block
|
57
|
+
# @return [Constructor]
|
43
58
|
def constructor(constructor = nil, **options, &block)
|
44
59
|
Constructor.new(with(options), fn: constructor || block)
|
45
60
|
end
|
data/lib/dry/types/coercions.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
|
-
require 'dry/core/constants'
|
2
|
-
|
3
1
|
module Dry
|
4
2
|
module Types
|
5
3
|
module Coercions
|
6
4
|
include Dry::Core::Constants
|
7
5
|
|
6
|
+
# @param [String] input
|
7
|
+
# @return [String?]
|
8
8
|
def to_nil(input)
|
9
9
|
input unless empty_str?(input)
|
10
10
|
end
|
11
11
|
|
12
|
+
# @param [#to_str, Object] input
|
13
|
+
# @return [Date, Object]
|
14
|
+
# @see Date.parse
|
12
15
|
def to_date(input)
|
13
16
|
return input unless input.respond_to?(:to_str)
|
14
17
|
Date.parse(input)
|
@@ -16,6 +19,9 @@ module Dry
|
|
16
19
|
input
|
17
20
|
end
|
18
21
|
|
22
|
+
# @param [#to_str, Object] input
|
23
|
+
# @return [DateTime, Object]
|
24
|
+
# @see DateTime.parse
|
19
25
|
def to_date_time(input)
|
20
26
|
return input unless input.respond_to?(:to_str)
|
21
27
|
DateTime.parse(input)
|
@@ -23,6 +29,9 @@ module Dry
|
|
23
29
|
input
|
24
30
|
end
|
25
31
|
|
32
|
+
# @param [#to_str, Object] input
|
33
|
+
# @return [Time, Object]
|
34
|
+
# @see Time.parse
|
26
35
|
def to_time(input)
|
27
36
|
return input unless input.respond_to?(:to_str)
|
28
37
|
Time.parse(input)
|
@@ -32,6 +41,9 @@ module Dry
|
|
32
41
|
|
33
42
|
private
|
34
43
|
|
44
|
+
# Checks whether String is empty
|
45
|
+
# @param [String, Object] value
|
46
|
+
# @return [Boolean]
|
35
47
|
def empty_str?(value)
|
36
48
|
EMPTY_STRING.eql?(value)
|
37
49
|
end
|
@@ -11,14 +11,24 @@ module Dry
|
|
11
11
|
|
12
12
|
extend Coercions
|
13
13
|
|
14
|
+
# @param [String, Object] input
|
15
|
+
# @return [Boolean?]
|
16
|
+
# @see TRUE_VALUES
|
17
|
+
# @see FALSE_VALUES
|
14
18
|
def self.to_true(input)
|
15
19
|
BOOLEAN_MAP.fetch(input.to_s, input)
|
16
20
|
end
|
17
21
|
|
22
|
+
# @param [String, Object] input
|
23
|
+
# @return [Boolean?]
|
24
|
+
# @see TRUE_VALUES
|
25
|
+
# @see FALSE_VALUES
|
18
26
|
def self.to_false(input)
|
19
27
|
BOOLEAN_MAP.fetch(input.to_s, input)
|
20
28
|
end
|
21
29
|
|
30
|
+
# @param [#to_int, #to_i, Object] input
|
31
|
+
# @return [Integer?, Object]
|
22
32
|
def self.to_int(input)
|
23
33
|
if empty_str?(input)
|
24
34
|
nil
|
@@ -29,6 +39,8 @@ module Dry
|
|
29
39
|
input
|
30
40
|
end
|
31
41
|
|
42
|
+
# @param [#to_f, Object] input
|
43
|
+
# @return [Float?, Object]
|
32
44
|
def self.to_float(input)
|
33
45
|
if empty_str?(input)
|
34
46
|
nil
|
@@ -39,6 +51,8 @@ module Dry
|
|
39
51
|
input
|
40
52
|
end
|
41
53
|
|
54
|
+
# @param [#to_d, Object] input
|
55
|
+
# @return [BigDecimal?, Object]
|
42
56
|
def self.to_decimal(input)
|
43
57
|
result = to_float(input)
|
44
58
|
|
@@ -49,10 +63,14 @@ module Dry
|
|
49
63
|
end
|
50
64
|
end
|
51
65
|
|
66
|
+
# @param [Array, '', Object] input
|
67
|
+
# @return [Array, Object]
|
52
68
|
def self.to_ary(input)
|
53
69
|
empty_str?(input) ? [] : input
|
54
70
|
end
|
55
71
|
|
72
|
+
# @param [Hash, '', Object] input
|
73
|
+
# @return [Hash]
|
56
74
|
def self.to_hash(input)
|
57
75
|
empty_str?(input) ? {} : input
|
58
76
|
end
|
@@ -9,13 +9,19 @@ module Dry
|
|
9
9
|
include Decorator
|
10
10
|
include Builder
|
11
11
|
|
12
|
+
# @return [Dry::Logic::Rule]
|
12
13
|
attr_reader :rule
|
13
14
|
|
15
|
+
# @param [Definition] type
|
16
|
+
# @param [Hash] options
|
14
17
|
def initialize(type, options)
|
15
18
|
super
|
16
19
|
@rule = options.fetch(:rule)
|
17
20
|
end
|
18
21
|
|
22
|
+
# @param [Object] input
|
23
|
+
# @return [Object]
|
24
|
+
# @raise [ConstraintError]
|
19
25
|
def call(input)
|
20
26
|
try(input) do |result|
|
21
27
|
raise ConstraintError.new(result, input)
|
@@ -23,6 +29,11 @@ module Dry
|
|
23
29
|
end
|
24
30
|
alias_method :[], :call
|
25
31
|
|
32
|
+
# @param [Object] input
|
33
|
+
# @param [#call] block
|
34
|
+
# @yieldparam [Failure] failure
|
35
|
+
# @yieldreturn [Result]
|
36
|
+
# @return [Result]
|
26
37
|
def try(input, &block)
|
27
38
|
result = rule.(input)
|
28
39
|
|
@@ -34,20 +45,30 @@ module Dry
|
|
34
45
|
end
|
35
46
|
end
|
36
47
|
|
48
|
+
# @param [Object] value
|
49
|
+
# @return [Boolean]
|
37
50
|
def valid?(value)
|
38
51
|
rule.(value).success? && type.valid?(value)
|
39
52
|
end
|
40
53
|
|
54
|
+
# @param [Hash] options
|
55
|
+
# The options hash provided to {Types.Rule} and combined
|
56
|
+
# using {&} with previous {#rule}
|
57
|
+
# @return [Constrained]
|
58
|
+
# @see Dry::Logic::Operators#and
|
41
59
|
def constrained(options)
|
42
60
|
with(rule: rule & Types.Rule(options))
|
43
61
|
end
|
44
62
|
|
63
|
+
# @return [true]
|
45
64
|
def constrained?
|
46
65
|
true
|
47
66
|
end
|
48
67
|
|
49
68
|
private
|
50
69
|
|
70
|
+
# @param [Object] response
|
71
|
+
# @return [Boolean]
|
51
72
|
def decorate?(response)
|
52
73
|
super || response.kind_of?(Constructor)
|
53
74
|
end
|