dry-monads 1.3.0 → 1.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +10 -39
  3. data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +10 -0
  4. data/.github/ISSUE_TEMPLATE/---bug-report.md +30 -0
  5. data/.github/ISSUE_TEMPLATE/---feature-request.md +18 -0
  6. data/.github/workflows/ci.yml +52 -0
  7. data/.github/workflows/docsite.yml +34 -0
  8. data/.github/workflows/sync_configs.yml +56 -0
  9. data/.rspec +1 -0
  10. data/.rubocop.yml +101 -0
  11. data/CHANGELOG.md +130 -62
  12. data/CODE_OF_CONDUCT.md +13 -0
  13. data/CONTRIBUTING.md +4 -4
  14. data/Gemfile +7 -8
  15. data/Gemfile.devtools +14 -0
  16. data/LICENSE +17 -17
  17. data/README.md +17 -38
  18. data/Rakefile +2 -0
  19. data/bin/.gitkeep +0 -0
  20. data/bin/console +1 -0
  21. data/docsite/source/case-equality.html.md +42 -0
  22. data/docsite/source/do-notation.html.md +207 -0
  23. data/docsite/source/getting-started.html.md +142 -0
  24. data/docsite/source/index.html.md +179 -0
  25. data/docsite/source/list.html.md +87 -0
  26. data/docsite/source/maybe.html.md +146 -0
  27. data/docsite/source/pattern-matching.html.md +68 -0
  28. data/docsite/source/result.html.md +190 -0
  29. data/docsite/source/task.html.md +126 -0
  30. data/docsite/source/tracing-failures.html.md +32 -0
  31. data/docsite/source/try.html.md +76 -0
  32. data/docsite/source/unit.html.md +36 -0
  33. data/docsite/source/validated.html.md +88 -0
  34. data/dry-monads.gemspec +7 -5
  35. data/lib/dry-monads.rb +2 -0
  36. data/lib/dry/monads.rb +3 -0
  37. data/lib/dry/monads/all.rb +2 -0
  38. data/lib/dry/monads/{undefined.rb → constants.rb} +3 -1
  39. data/lib/dry/monads/conversion_stubs.rb +2 -0
  40. data/lib/dry/monads/curry.rb +2 -0
  41. data/lib/dry/monads/do.rb +7 -2
  42. data/lib/dry/monads/do/all.rb +5 -2
  43. data/lib/dry/monads/do/mixin.rb +4 -3
  44. data/lib/dry/monads/either.rb +2 -0
  45. data/lib/dry/monads/errors.rb +4 -2
  46. data/lib/dry/monads/lazy.rb +4 -2
  47. data/lib/dry/monads/list.rb +10 -9
  48. data/lib/dry/monads/maybe.rb +9 -4
  49. data/lib/dry/monads/registry.rb +5 -2
  50. data/lib/dry/monads/result.rb +5 -4
  51. data/lib/dry/monads/result/fixed.rb +4 -2
  52. data/lib/dry/monads/right_biased.rb +55 -8
  53. data/lib/dry/monads/task.rb +6 -3
  54. data/lib/dry/monads/transformer.rb +2 -0
  55. data/lib/dry/monads/traverse.rb +2 -0
  56. data/lib/dry/monads/try.rb +6 -1
  57. data/lib/dry/monads/validated.rb +12 -9
  58. data/lib/dry/monads/version.rb +3 -1
  59. data/lib/json/add/dry/monads/maybe.rb +1 -0
  60. data/project.yml +2 -0
  61. metadata +45 -22
  62. data/.travis.yml +0 -41
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/equalizer'
2
4
 
3
- require 'dry/monads/undefined'
5
+ require 'dry/monads/constants'
4
6
  require 'dry/monads/right_biased'
5
7
  require 'dry/monads/transformer'
6
8
  require 'dry/monads/conversion_stubs'
@@ -299,7 +301,6 @@ module Dry
299
301
  # Value constructors
300
302
  #
301
303
  module Constructors
302
-
303
304
  # Success constructor
304
305
  #
305
306
  # @overload Success(value)
@@ -386,7 +387,7 @@ module Dry
386
387
  # @param fail [#call] Fallback value
387
388
  # @param block [Proc] Fallback block
388
389
  # @return [Success<Any>]
389
- def to_result(fail = Unit, &block)
390
+ def to_result(_fail = Unit)
390
391
  Result::Success.new(@value)
391
392
  end
392
393
  end
@@ -397,7 +398,7 @@ module Dry
397
398
  # @param fail [#call] Fallback value
398
399
  # @param block [Proc] Fallback block
399
400
  # @return [Failure<Any>]
400
- def to_result(fail = Unit, &block)
401
+ def to_result(fail = Unit)
401
402
  if block_given?
402
403
  Result::Failure.new(yield)
403
404
  else
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dry::Monads
2
4
  class Result
3
5
  # @see Monads#Result
@@ -7,13 +9,13 @@ module Dry::Monads
7
9
  new(error, **options)
8
10
  end
9
11
 
10
- def initialize(error, **options)
12
+ def initialize(error, **_options)
11
13
  @mod = Module.new do
12
14
  define_method(:Failure) do |value|
13
15
  if error === value
14
16
  Failure.new(value, RightBiased::Left.trace_caller)
15
17
  else
16
- raise InvalidFailureTypeError.new(value)
18
+ raise InvalidFailureTypeError, value
17
19
  end
18
20
  end
19
21
 
@@ -1,5 +1,6 @@
1
- require 'dry/core/constants'
1
+ # frozen_string_literal: true
2
2
 
3
+ require 'dry/monads/constants'
3
4
  require 'dry/monads/unit'
4
5
  require 'dry/monads/curry'
5
6
  require 'dry/monads/errors'
@@ -12,8 +13,6 @@ module Dry
12
13
  #
13
14
  # @api public
14
15
  module Right
15
- include Dry::Core::Constants
16
-
17
16
  # @private
18
17
  def self.included(m)
19
18
  super
@@ -121,7 +120,7 @@ module Dry
121
120
  # @return [RightBiased::Left,RightBiased::Right]
122
121
  def apply(val = Undefined)
123
122
  unless @value.respond_to?(:call)
124
- raise TypeError, "Cannot apply #{ val.inspect } to #{ @value.inspect }"
123
+ raise TypeError, "Cannot apply #{val.inspect} to #{@value.inspect}"
125
124
  end
126
125
 
127
126
  Undefined.default(val) { yield }.fmap { |unwrapped| curry.(unwrapped) }
@@ -194,6 +193,7 @@ module Dry
194
193
  # in Success(2..100) then ...
195
194
  # in Success(2..200 => code) then ...
196
195
  # end
196
+ #
197
197
  # @api private
198
198
  def deconstruct
199
199
  if Unit.equal?(@value)
@@ -205,11 +205,41 @@ module Dry
205
205
  end
206
206
  end
207
207
 
208
+ # Pattern matching hash values
209
+ #
210
+ # @example
211
+ # case Success(x)
212
+ # in Success(code: 200...300) then :ok
213
+ # in Success(code: 300...400) then :redirect
214
+ # in Success(code: 400...500) then :user_error
215
+ # in Success(code: 500...600) then :server_error
216
+ # end
217
+ #
218
+ # @api private
219
+ def deconstruct_keys(keys)
220
+ if @value.respond_to?(:deconstruct_keys)
221
+ @value.deconstruct_keys(keys)
222
+ else
223
+ EMPTY_HASH
224
+ end
225
+ end
226
+
208
227
  private
209
228
 
210
- # @api private
211
- def destructure(*args, **kwargs)
212
- [args, kwargs]
229
+ if RUBY_VERSION >= '2.7'
230
+ # @api private
231
+ def destructure(value)
232
+ if value.is_a?(::Hash)
233
+ [EMPTY_ARRAY, value]
234
+ else
235
+ [[value], EMPTY_HASH]
236
+ end
237
+ end
238
+ else
239
+ # @api private
240
+ def destructure(*args, **kwargs)
241
+ [args, kwargs]
242
+ end
213
243
  end
214
244
 
215
245
  # @api private
@@ -230,7 +260,7 @@ module Dry
230
260
 
231
261
  # Raises an error on accessing internal value
232
262
  def value!
233
- raise UnwrapError.new(self)
263
+ raise UnwrapError, self
234
264
  end
235
265
 
236
266
  # Ignores the input parameter and returns self. It exists to keep the interface
@@ -343,6 +373,23 @@ module Dry
343
373
  [@value]
344
374
  end
345
375
  end
376
+
377
+ # Pattern matching hash values
378
+ #
379
+ # @example
380
+ # case Failure(x)
381
+ # in Failure(code: 400...500) then :user_error
382
+ # in Failure(code: 500...600) then :server_error
383
+ # end
384
+ #
385
+ # @api private
386
+ def deconstruct_keys(keys)
387
+ if @value.respond_to?(:deconstruct_keys)
388
+ @value.deconstruct_keys(keys)
389
+ else
390
+ EMPTY_HASH
391
+ end
392
+ end
346
393
  end
347
394
  end
348
395
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'concurrent/promise'
2
4
 
3
5
  require 'dry/monads/unit'
@@ -134,7 +136,7 @@ module Dry
134
136
  "value=#{value!.inspect}"
135
137
  end
136
138
  when :rejected
137
- "error=#{ promise.reason.inspect }"
139
+ "error=#{promise.reason.inspect}"
138
140
  else
139
141
  '?'
140
142
  end
@@ -167,11 +169,11 @@ module Dry
167
169
  inner.execute
168
170
  inner.on_success { |r| child.on_fulfill(r) }
169
171
  inner.on_error { |e| child.on_reject(e) }
170
- rescue => e
172
+ rescue StandardError => e
171
173
  child.on_reject(e)
172
174
  end
173
175
  end
174
- promise.on_success { |v| child.on_fulfill(v) }
176
+ promise.on_success { |v| child.on_fulfill(v) }
175
177
 
176
178
  self.class.new(child)
177
179
  end
@@ -200,6 +202,7 @@ module Dry
200
202
  def ==(other)
201
203
  return true if equal?(other)
202
204
  return false unless self.class == other.class
205
+
203
206
  compare_promises(promise, other.promise)
204
207
  end
205
208
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dry
2
4
  module Monads
3
5
  # Advanced tranformations.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/monads/validated'
2
4
 
3
5
  module Dry
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/equalizer'
2
4
  require 'dry/core/deprecations'
3
5
 
@@ -71,6 +73,7 @@ module Dry
71
73
  # @return [Try::Value,Try::Error]
72
74
  def [](*exceptions, &block)
73
75
  raise ArgumentError, 'At least one exception type required' if exceptions.empty?
76
+
74
77
  run(exceptions, block)
75
78
  end
76
79
  end
@@ -181,7 +184,7 @@ module Dry
181
184
 
182
185
  # @return [String]
183
186
  def to_s
184
- "Try::Error(#{ exception.class }: #{ exception.message })"
187
+ "Try::Error(#{exception.class}: #{exception.message})"
185
188
  end
186
189
  alias_method :inspect, :to_s
187
190
 
@@ -259,6 +262,7 @@ module Dry
259
262
  def Value(value = Undefined, exceptions = DEFAULT_EXCEPTIONS, &block)
260
263
  v = Undefined.default(value, block)
261
264
  raise ArgumentError, 'No value given' if !value.nil? && v.nil?
265
+
262
266
  Value.new(exceptions, v)
263
267
  end
264
268
 
@@ -275,6 +279,7 @@ module Dry
275
279
  def Error(error = Undefined, &block)
276
280
  v = Undefined.default(error, block)
277
281
  raise ArgumentError, 'No value given' if v.nil?
282
+
278
283
  Try::Error.new(v)
279
284
  end
280
285
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'dry/monads/conversion_stubs'
2
- require 'dry/monads/undefined'
4
+ require 'dry/monads/constants'
3
5
  require 'dry/monads/right_biased'
4
6
 
5
7
  module Dry
@@ -49,7 +51,7 @@ module Dry
49
51
  #
50
52
  def bind(*)
51
53
  # See https://typelevel.org/cats/datatypes/validated.html for details on why
52
- raise NotImplementedError, "Validated is not a monad because it would violate the monad laws"
54
+ raise NotImplementedError, 'Validated is not a monad because it would violate the monad laws'
53
55
  end
54
56
 
55
57
  # Valid result
@@ -121,7 +123,7 @@ module Dry
121
123
  # @return [String]
122
124
  def inspect
123
125
  if Unit.equal?(@value)
124
- "Valid()"
126
+ 'Valid()'
125
127
  else
126
128
  "Valid(#{@value.inspect})"
127
129
  end
@@ -167,10 +169,10 @@ module Dry
167
169
  # @return [Validated::Invalid]
168
170
  #
169
171
  def apply(val = Undefined)
170
- Undefined.
171
- default(val) { yield }.
172
- alt_map { |v| @error + v }.
173
- fmap { return self }
172
+ Undefined
173
+ .default(val) { yield }
174
+ .alt_map { |v| @error + v }
175
+ .fmap { return self }
174
176
  end
175
177
 
176
178
  # Lifts a block/proc over Invalid
@@ -211,7 +213,7 @@ module Dry
211
213
 
212
214
  # @return [String]
213
215
  def inspect
214
- "Invalid(#{ @error.inspect })"
216
+ "Invalid(#{@error.inspect})"
215
217
  end
216
218
  alias_method :to_s, :inspect
217
219
 
@@ -225,7 +227,6 @@ module Dry
225
227
  # Mixin with Validated constructors
226
228
  #
227
229
  module Mixin
228
-
229
230
  # Successful validation result
230
231
  # @see Dry::Monads::Validated::Valid
231
232
  Valid = Valid
@@ -250,6 +251,7 @@ module Dry
250
251
  def Valid(value = Undefined, &block)
251
252
  v = Undefined.default(value, block)
252
253
  raise ArgumentError, 'No value given' if !value.nil? && v.nil?
254
+
253
255
  Valid.new(v)
254
256
  end
255
257
 
@@ -266,6 +268,7 @@ module Dry
266
268
  def Invalid(value = Undefined, &block)
267
269
  v = Undefined.default(value, block)
268
270
  raise ArgumentError, 'No value given' if !value.nil? && v.nil?
271
+
269
272
  Invalid.new(v, RightBiased::Left.trace_caller)
270
273
  end
271
274
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dry
2
4
  module Monads
3
5
  # Gem version
4
- VERSION = '1.3.0'.freeze
6
+ VERSION = '1.3.5'
5
7
  end
6
8
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: false
2
+
2
3
  require 'json' unless defined?(::JSON::JSON_LOADED) && ::JSON::JSON_LOADED
3
4
 
4
5
  require 'dry/monads'
@@ -0,0 +1,2 @@
1
+ name: dry-monads
2
+ codacy_id: f2eed41bf7f04b38b0a7691c2cf6e73c
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-monads
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Shilnikov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-03 00:00:00.000000000 Z
11
+ date: 2020-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: dry-equalizer
14
+ name: concurrent-ruby
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: dry-core
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -45,19 +45,19 @@ dependencies:
45
45
  - !ruby/object:Gem::Version
46
46
  version: 0.4.4
47
47
  - !ruby/object:Gem::Dependency
48
- name: concurrent-ruby
48
+ name: dry-equalizer
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - "~>"
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: '1.0'
53
+ version: '0'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - "~>"
58
+ - - ">="
59
59
  - !ruby/object:Gem::Version
60
- version: '1.0'
60
+ version: '0'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: bundler
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -73,21 +73,21 @@ dependencies:
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
75
  - !ruby/object:Gem::Dependency
76
- name: rake
76
+ name: dry-types
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - ">="
80
80
  - !ruby/object:Gem::Version
81
- version: '0'
81
+ version: '0.12'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
- version: '0'
88
+ version: '0.12'
89
89
  - !ruby/object:Gem::Dependency
90
- name: rspec
90
+ name: rake
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - ">="
@@ -101,19 +101,19 @@ dependencies:
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
103
  - !ruby/object:Gem::Dependency
104
- name: dry-types
104
+ name: rspec
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - ">="
108
108
  - !ruby/object:Gem::Version
109
- version: '0.12'
109
+ version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
- version: '0.12'
116
+ version: '0'
117
117
  description: Common monads for Ruby.
118
118
  email:
119
119
  - fg@flashgordon.ru
@@ -122,22 +122,45 @@ extensions: []
122
122
  extra_rdoc_files: []
123
123
  files:
124
124
  - ".codeclimate.yml"
125
+ - ".github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md"
126
+ - ".github/ISSUE_TEMPLATE/---bug-report.md"
127
+ - ".github/ISSUE_TEMPLATE/---feature-request.md"
128
+ - ".github/workflows/ci.yml"
129
+ - ".github/workflows/docsite.yml"
130
+ - ".github/workflows/sync_configs.yml"
125
131
  - ".gitignore"
126
132
  - ".rspec"
127
- - ".travis.yml"
133
+ - ".rubocop.yml"
128
134
  - ".yardopts"
129
135
  - CHANGELOG.md
136
+ - CODE_OF_CONDUCT.md
130
137
  - CONTRIBUTING.md
131
138
  - Gemfile
139
+ - Gemfile.devtools
132
140
  - LICENSE
133
141
  - README.md
134
142
  - Rakefile
143
+ - bin/.gitkeep
135
144
  - bin/console
136
145
  - bin/setup
146
+ - docsite/source/case-equality.html.md
147
+ - docsite/source/do-notation.html.md
148
+ - docsite/source/getting-started.html.md
149
+ - docsite/source/index.html.md
150
+ - docsite/source/list.html.md
151
+ - docsite/source/maybe.html.md
152
+ - docsite/source/pattern-matching.html.md
153
+ - docsite/source/result.html.md
154
+ - docsite/source/task.html.md
155
+ - docsite/source/tracing-failures.html.md
156
+ - docsite/source/try.html.md
157
+ - docsite/source/unit.html.md
158
+ - docsite/source/validated.html.md
137
159
  - dry-monads.gemspec
138
160
  - lib/dry-monads.rb
139
161
  - lib/dry/monads.rb
140
162
  - lib/dry/monads/all.rb
163
+ - lib/dry/monads/constants.rb
141
164
  - lib/dry/monads/conversion_stubs.rb
142
165
  - lib/dry/monads/curry.rb
143
166
  - lib/dry/monads/do.rb
@@ -156,12 +179,12 @@ files:
156
179
  - lib/dry/monads/transformer.rb
157
180
  - lib/dry/monads/traverse.rb
158
181
  - lib/dry/monads/try.rb
159
- - lib/dry/monads/undefined.rb
160
182
  - lib/dry/monads/unit.rb
161
183
  - lib/dry/monads/validated.rb
162
184
  - lib/dry/monads/version.rb
163
185
  - lib/json/add/dry/monads/maybe.rb
164
186
  - log/.gitkeep
187
+ - project.yml
165
188
  homepage: https://github.com/dry-rb/dry-monads
166
189
  licenses:
167
190
  - MIT
@@ -182,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
205
  - !ruby/object:Gem::Version
183
206
  version: '0'
184
207
  requirements: []
185
- rubygems_version: 3.0.3
208
+ rubygems_version: 3.1.2
186
209
  signing_key:
187
210
  specification_version: 4
188
211
  summary: Common monads for Ruby.