dry-monads 1.3.0 → 1.3.5

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.
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.