dry-monads 1.9.0 → 1.11.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 +133 -104
- data/LICENSE +1 -1
- data/README.md +13 -13
- data/dry-monads.gemspec +20 -15
- data/lib/dry/monads/do/mixin.rb +2 -2
- data/lib/dry/monads/do.rb +1 -1
- data/lib/dry/monads/extensions/json.rb +128 -0
- data/lib/dry/monads/extensions/rspec.rb +35 -3
- data/lib/dry/monads/extensions.rb +4 -0
- data/lib/dry/monads/list.rb +6 -3
- data/lib/dry/monads/maybe.rb +8 -5
- data/lib/dry/monads/result.rb +1 -1
- data/lib/dry/monads/right_biased.rb +14 -7
- data/lib/dry/monads/task.rb +3 -3
- data/lib/dry/monads/transformer.rb +1 -1
- data/lib/dry/monads/try.rb +7 -7
- data/lib/dry/monads/unit.rb +1 -1
- data/lib/dry/monads/validated.rb +1 -1
- data/lib/dry/monads/version.rb +1 -1
- data/lib/dry/monads.rb +0 -1
- metadata +69 -14
- data/lib/json/add/dry/monads/maybe.rb +0 -32
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 74c983b4b86f5bc73455c3f8987760ae5e11d026f87fbcb4741da18051c60e10
|
|
4
|
+
data.tar.gz: 42b72b1ab09dab98fe8c5a399d17d882a2fdcdf45971ec70e29868fbb07dfcba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d7afa3e95783b08fb767e1ad0b4be5aa5e3e3bf096e534884783a419acc62ccbc141fbdf641a673b9a2808b6bf27fdfb2ca64dc7e0360adbaff7f587353b3357
|
|
7
|
+
data.tar.gz: 831f701ceb7e787bab8d4c77f159aeaa1a13c5c387c790e2c50fe78a8c50a9d9d0610893466eb3f06ae73b9cbd31c08fcf45f0a8dc6822d203949abafce23870
|
data/CHANGELOG.md
CHANGED
|
@@ -1,51 +1,121 @@
|
|
|
1
|
-
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Break Versioning](https://www.taoensso.com/break-versioning).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
5
9
|
|
|
6
10
|
### Added
|
|
7
11
|
|
|
8
|
-
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
### Deprecated
|
|
15
|
+
|
|
16
|
+
### Removed
|
|
9
17
|
|
|
10
18
|
### Fixed
|
|
11
19
|
|
|
12
|
-
|
|
20
|
+
### Security
|
|
21
|
+
|
|
22
|
+
[Unreleased]: https://github.com/dry-rb/dry-monads/compare/v1.10.0...main
|
|
23
|
+
|
|
24
|
+
## [1.11.0] - 2026-09-11
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- New `:json` extension, which builds a `JSON::Coder` that reads and writes monads. It needs the json gem 2.15.0 or later. (@timriley in #209)
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
Dry::Monads.load_extensions(:json)
|
|
32
|
+
|
|
33
|
+
coder = Dry::Monads.json_coder
|
|
34
|
+
coder.dump(Some(3)) # => %({"json_class":"Dry::Monads::Maybe::Some","value":3})
|
|
35
|
+
coder.load(%({"json_class":"Dry::Monads::Maybe::Some","value":3})) # => Some(3)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Give `json_coder` an `as_json:` and an `on_load:` callback to handle your own types in the same coder. Both run after the monad callbacks, and your types and monads can nest inside each other:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
coder = Dry::Monads.json_coder(
|
|
42
|
+
as_json: ->(object, *) {
|
|
43
|
+
object.is_a?(Time) ? {"json_class" => "Time", "value" => object.iso8601} : object
|
|
44
|
+
},
|
|
45
|
+
on_load: ->(value) {
|
|
46
|
+
value.is_a?(Hash) && value["json_class"] == "Time" ? Time.iso8601(value["value"]) : value
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Removed
|
|
13
52
|
|
|
53
|
+
- **Breaking**: removed `json/add/dry/monads/maybe`. The json gem 3.0 removed the whole `json/add` mechanism, so monads can no longer hook into `JSON.dump` and `JSON.load` globally. Use the new `:json` extension instead. (@timriley in #209)
|
|
14
54
|
|
|
15
|
-
|
|
55
|
+
```ruby
|
|
56
|
+
# before
|
|
57
|
+
require "json/add/dry/monads/maybe"
|
|
58
|
+
JSON.unsafe_load(JSON.dump(data))
|
|
59
|
+
|
|
60
|
+
# after
|
|
61
|
+
Dry::Monads.load_extensions(:json)
|
|
62
|
+
coder = Dry::Monads.json_coder
|
|
63
|
+
coder.load(coder.dump(data))
|
|
64
|
+
```
|
|
16
65
|
|
|
17
|
-
|
|
66
|
+
The JSON serialization format is the same as before, so JSON written by the old serializer still loads. One behavior differs: `JSON::Coder` will always raise a `JSON::GeneratorError` when it sees an object with no JSON counterpart raises, instead of falling back to `to_s`.
|
|
18
67
|
|
|
68
|
+
[1.11.0]: https://github.com/dry-rb/dry-monads/compare/v1.10.0...v1.11.0
|
|
69
|
+
|
|
70
|
+
## [1.10.0] - 2026-04-24
|
|
71
|
+
|
|
72
|
+
### Added
|
|
73
|
+
|
|
74
|
+
- Support for JRuby (via fixes to RSpec extension). (@katafrakt in #200 & #201, @flash-gordon in c6967b6)
|
|
19
75
|
|
|
20
76
|
### Fixed
|
|
21
77
|
|
|
22
|
-
- Fix
|
|
78
|
+
- Fix param names and Ruby syntax in API doc examples. (@mensfeld in #196)
|
|
23
79
|
|
|
80
|
+
[1.10.0]: https://github.com/dry-rb/dry-monads/compare/v1.9.0...v1.10.0
|
|
24
81
|
|
|
25
|
-
[
|
|
82
|
+
## [1.9.0] - 2025-06-24
|
|
26
83
|
|
|
27
|
-
|
|
84
|
+
### Added
|
|
28
85
|
|
|
86
|
+
- Add `pretty_print` extension for improved output (@paul + @flash-gordon in #189 and #190)
|
|
29
87
|
|
|
30
88
|
### Fixed
|
|
31
89
|
|
|
32
|
-
- Fix
|
|
90
|
+
- Fix nested modules not being extended in RSpec (@flash-gordon)
|
|
91
|
+
|
|
92
|
+
[1.9.0]: https://github.com/dry-rb/dry-monads/compare/v1.8.3...v1.9.0
|
|
33
93
|
|
|
94
|
+
## [1.8.3] - 2025-04-04
|
|
34
95
|
|
|
35
|
-
|
|
96
|
+
### Fixed
|
|
97
|
+
|
|
98
|
+
- Fix signature of warning filter (@flash-gordon, issue #187)
|
|
36
99
|
|
|
37
|
-
|
|
100
|
+
[1.8.3]: https://github.com/dry-rb/dry-monads/compare/v1.8.2...v1.8.3
|
|
38
101
|
|
|
102
|
+
## [1.8.2] - 2025-03-15
|
|
39
103
|
|
|
40
104
|
### Fixed
|
|
41
105
|
|
|
42
|
-
-
|
|
106
|
+
- Fix be_* matchers for non-monadic values (@flash-gordon, issue #186)
|
|
107
|
+
|
|
108
|
+
[1.8.2]: https://github.com/dry-rb/dry-monads/compare/v1.8.1...v1.8.2
|
|
43
109
|
|
|
110
|
+
## [1.8.1] - 2025-03-12
|
|
111
|
+
|
|
112
|
+
### Fixed
|
|
44
113
|
|
|
45
|
-
|
|
114
|
+
- Exclude extensions from the Zeitwerk loader (@flash-gordon, issue #185)
|
|
46
115
|
|
|
47
|
-
|
|
116
|
+
[1.8.1]: https://github.com/dry-rb/dry-monads/compare/v1.8.0...v1.8.1
|
|
48
117
|
|
|
118
|
+
## [1.8.0] - 2025-03-12
|
|
49
119
|
|
|
50
120
|
### Added
|
|
51
121
|
|
|
@@ -141,21 +211,17 @@
|
|
|
141
211
|
)
|
|
142
212
|
```
|
|
143
213
|
|
|
214
|
+
[1.8.0]: https://github.com/dry-rb/dry-monads/compare/v1.7.1...v1.8.0
|
|
144
215
|
|
|
145
|
-
[
|
|
146
|
-
|
|
147
|
-
## 1.7.1 2025-01-21
|
|
148
|
-
|
|
216
|
+
## [1.7.1] - 2025-01-21
|
|
149
217
|
|
|
150
218
|
### Fixed
|
|
151
219
|
|
|
152
220
|
- Fix warnings about unused block arguments (@flash-gordon)
|
|
153
221
|
|
|
222
|
+
[1.7.1]: https://github.com/dry-rb/dry-monads/compare/v1.7.0...v1.7.1
|
|
154
223
|
|
|
155
|
-
[
|
|
156
|
-
|
|
157
|
-
## 1.7.0 2025-01-07
|
|
158
|
-
|
|
224
|
+
## [1.7.0] - 2025-01-07
|
|
159
225
|
|
|
160
226
|
### Fixed
|
|
161
227
|
|
|
@@ -165,19 +231,17 @@
|
|
|
165
231
|
|
|
166
232
|
- Set 3.1 as minimum Ruby version (@flash-gordon)
|
|
167
233
|
|
|
168
|
-
[
|
|
169
|
-
|
|
170
|
-
## 1.6.0 2022-11-04
|
|
234
|
+
[1.7.0]: https://github.com/dry-rb/dry-monads/compare/v1.6.0...v1.7.0
|
|
171
235
|
|
|
236
|
+
## [1.6.0] - 2022-11-04
|
|
172
237
|
|
|
173
238
|
### Changed
|
|
174
239
|
|
|
175
240
|
- This version uses dry-core 1.0 (@flash-gordon)
|
|
176
241
|
|
|
177
|
-
[
|
|
178
|
-
|
|
179
|
-
## 1.5.0 2022-10-16
|
|
242
|
+
[1.6.0]: https://github.com/dry-rb/dry-monads/compare/v1.5.0...v1.6.0
|
|
180
243
|
|
|
244
|
+
## [1.5.0] - 2022-10-16
|
|
181
245
|
|
|
182
246
|
### Changed
|
|
183
247
|
|
|
@@ -186,10 +250,9 @@
|
|
|
186
250
|
- Minimal Ruby version is now 2.7 (@flash-gordon)
|
|
187
251
|
- Either (old name of Result) was removed (@flash-gordon)
|
|
188
252
|
|
|
189
|
-
[
|
|
190
|
-
|
|
191
|
-
## 1.4.0 2021-07-20
|
|
253
|
+
[1.5.0]: https://github.com/dry-rb/dry-monads/compare/v1.4.0...v1.5.0
|
|
192
254
|
|
|
255
|
+
## [1.4.0] - 2021-07-20
|
|
193
256
|
|
|
194
257
|
### Added
|
|
195
258
|
|
|
@@ -238,40 +301,33 @@ This behavior will be dropped in 2.0 but you can opt out of warnings for the tim
|
|
|
238
301
|
```
|
|
239
302
|
- Minimal Ruby version is 2.6
|
|
240
303
|
|
|
241
|
-
[
|
|
242
|
-
|
|
243
|
-
## 1.3.5 2020-01-06
|
|
304
|
+
[1.4.0]: https://github.com/dry-rb/dry-monads/compare/v1.3.5...v1.4.0
|
|
244
305
|
|
|
306
|
+
## [1.3.5] - 2020-01-06
|
|
245
307
|
|
|
246
308
|
### Added
|
|
247
309
|
|
|
248
310
|
- Smarter keys deconstruction in pattern matching (flash-gordon)
|
|
249
311
|
|
|
312
|
+
[1.3.5]: https://github.com/dry-rb/dry-monads/compare/v1.3.4...v1.3.5
|
|
250
313
|
|
|
251
|
-
[
|
|
252
|
-
|
|
253
|
-
## 1.3.4 2019-12-28
|
|
254
|
-
|
|
314
|
+
## [1.3.4] - 2019-12-28
|
|
255
315
|
|
|
256
316
|
### Fixed
|
|
257
317
|
|
|
258
318
|
- One more delegation warning happenning in do notation (flash-gordon)
|
|
259
319
|
|
|
320
|
+
[1.3.4]: https://github.com/dry-rb/dry-monads/compare/v1.3.3...v1.3.4
|
|
260
321
|
|
|
261
|
-
[
|
|
262
|
-
|
|
263
|
-
## 1.3.3 2019-12-11
|
|
264
|
-
|
|
322
|
+
## [1.3.3] - 2019-12-11
|
|
265
323
|
|
|
266
324
|
### Fixed
|
|
267
325
|
|
|
268
326
|
- Incompatibility with Rails. Internal (!) halt exceptions now use mutable backtraces because spring [mutates](https://github.com/rails/spring/blob/ee687859008e947bc905b95121e306e2948d31c9/lib/spring/application.rb#L295-L311) (!) them. For the record, this a bug in Rails (johnmaxwell)
|
|
269
327
|
|
|
328
|
+
[1.3.3]: https://github.com/dry-rb/dry-monads/compare/v1.3.2...v1.3.3
|
|
270
329
|
|
|
271
|
-
[
|
|
272
|
-
|
|
273
|
-
## 1.3.2 2019-11-30
|
|
274
|
-
|
|
330
|
+
## [1.3.2] - 2019-11-30
|
|
275
331
|
|
|
276
332
|
### Added
|
|
277
333
|
|
|
@@ -288,21 +344,17 @@ This behavior will be dropped in 2.0 but you can opt out of warnings for the tim
|
|
|
288
344
|
|
|
289
345
|
- Warnings about keywords from Ruby 2.7 (flash-gordon)
|
|
290
346
|
|
|
347
|
+
[1.3.2]: https://github.com/dry-rb/dry-monads/compare/v1.3.1...v1.3.2
|
|
291
348
|
|
|
292
|
-
[
|
|
293
|
-
|
|
294
|
-
## 1.3.1 2019-09-07
|
|
295
|
-
|
|
349
|
+
## [1.3.1] - 2019-09-07
|
|
296
350
|
|
|
297
351
|
### Fixed
|
|
298
352
|
|
|
299
353
|
- Added missing `None#maybe` :sweat_smile: (flash-gordon)
|
|
300
354
|
|
|
355
|
+
[1.3.1]: https://github.com/dry-rb/dry-monads/compare/v1.3.0...v1.3.1
|
|
301
356
|
|
|
302
|
-
[
|
|
303
|
-
|
|
304
|
-
## 1.3.0 2019-08-03
|
|
305
|
-
|
|
357
|
+
## [1.3.0] - 2019-08-03
|
|
306
358
|
|
|
307
359
|
### Added
|
|
308
360
|
|
|
@@ -385,11 +437,9 @@ This behavior will be dropped in 2.0 but you can opt out of warnings for the tim
|
|
|
385
437
|
|
|
386
438
|
Keep in mind this feature is experimental and can be changed by 2.7 release. But it rocks already!
|
|
387
439
|
|
|
440
|
+
[1.3.0]: https://github.com/dry-rb/dry-monads/compare/v1.2.0...v1.3.0
|
|
388
441
|
|
|
389
|
-
[
|
|
390
|
-
|
|
391
|
-
## 1.2.0 2019-01-12
|
|
392
|
-
|
|
442
|
+
## [1.2.0] - 2019-01-12
|
|
393
443
|
|
|
394
444
|
### Added
|
|
395
445
|
|
|
@@ -477,11 +527,9 @@ This behavior will be dropped in 2.0 but you can opt out of warnings for the tim
|
|
|
477
527
|
```
|
|
478
528
|
- `Task.failed` is a counterpart of `Task.pure`, accepts an exception and returns a failed task immediately (flash-gordon)
|
|
479
529
|
|
|
530
|
+
[1.2.0]: https://github.com/dry-rb/dry-monads/compare/v1.1.0...v1.2.0
|
|
480
531
|
|
|
481
|
-
[
|
|
482
|
-
|
|
483
|
-
## 1.1.0 2018-10-16
|
|
484
|
-
|
|
532
|
+
## [1.1.0] - 2018-10-16
|
|
485
533
|
|
|
486
534
|
### Added
|
|
487
535
|
|
|
@@ -503,11 +551,9 @@ This behavior will be dropped in 2.0 but you can opt out of warnings for the tim
|
|
|
503
551
|
|
|
504
552
|
- Do notation was made to work nicely with inheritance. This shouldn't break any existing code but if it does please report (flash-gordon)
|
|
505
553
|
|
|
554
|
+
[1.1.0]: https://github.com/dry-rb/dry-monads/compare/v1.0.1...v1.1.0
|
|
506
555
|
|
|
507
|
-
[
|
|
508
|
-
|
|
509
|
-
## 1.0.1 2018-08-11
|
|
510
|
-
|
|
556
|
+
## [1.0.1] - 2018-08-11
|
|
511
557
|
|
|
512
558
|
### Added
|
|
513
559
|
|
|
@@ -520,11 +566,9 @@ This behavior will be dropped in 2.0 but you can opt out of warnings for the tim
|
|
|
520
566
|
|
|
521
567
|
- Fixed behavior of `List<Validated>#traverse` in presence of `Valid` values (flash-gordon + SunnyMagadan)
|
|
522
568
|
|
|
569
|
+
[1.0.1]: https://github.com/dry-rb/dry-monads/compare/v1.0.0...v1.0.1
|
|
523
570
|
|
|
524
|
-
[
|
|
525
|
-
|
|
526
|
-
## 1.0.0 2018-06-26
|
|
527
|
-
|
|
571
|
+
## [1.0.0] - 2018-06-26
|
|
528
572
|
|
|
529
573
|
### Added
|
|
530
574
|
|
|
@@ -662,11 +706,9 @@ This behavior will be dropped in 2.0 but you can opt out of warnings for the tim
|
|
|
662
706
|
- `Either#value` and `Maybe#value` were both droped, use `value_or` or `value!` when you :100: sure it's safe
|
|
663
707
|
- `require 'dry/monads'` doesn't load all monads anymore, use `require 'dry/monads/all'` instead or cherry pick them with `require 'dry/monads/maybe'` etc (timriley)
|
|
664
708
|
|
|
709
|
+
[1.0.0]: https://github.com/dry-rb/dry-monads/compare/v0.4.0...v1.0.0
|
|
665
710
|
|
|
666
|
-
[
|
|
667
|
-
|
|
668
|
-
## 0.4.0 2017-11-11
|
|
669
|
-
|
|
711
|
+
## [0.4.0] - 2017-11-11
|
|
670
712
|
|
|
671
713
|
### Added
|
|
672
714
|
|
|
@@ -691,20 +733,17 @@ This behavior will be dropped in 2.0 but you can opt out of warnings for the tim
|
|
|
691
733
|
- The `Either` monad was renamed to `Result` which sounds less nerdy but better reflects the purpose of the type. `Either::Right` became `Result::Success` and `Either::Left` became `Result::Failure`. This change is backward-compatible overall but you will see the new names when using old `Left` and `Right` methods (citizen428)
|
|
692
734
|
- Consequently, `Try::Success` and `Try::Failure` were renamed to `Try::Value` and `Try::Error` (flash-gordon)
|
|
693
735
|
|
|
694
|
-
[
|
|
695
|
-
|
|
696
|
-
## 0.3.1 2017-03-18
|
|
736
|
+
[0.4.0]: https://github.com/dry-rb/dry-monads/compare/v0.3.1...v0.4.0
|
|
697
737
|
|
|
738
|
+
## [0.3.1] - 2017-03-18
|
|
698
739
|
|
|
699
740
|
### Fixed
|
|
700
741
|
|
|
701
742
|
- Fixed unexpected coercing to `Hash` on `.bind` call (flash-gordon)
|
|
702
743
|
|
|
744
|
+
[0.3.1]: https://github.com/dry-rb/dry-monads/compare/v0.3.0...v0.3.1
|
|
703
745
|
|
|
704
|
-
[
|
|
705
|
-
|
|
706
|
-
## 0.3.0 2017-03-16
|
|
707
|
-
|
|
746
|
+
## [0.3.0] - 2017-03-16
|
|
708
747
|
|
|
709
748
|
### Added
|
|
710
749
|
|
|
@@ -716,11 +755,9 @@ This behavior will be dropped in 2.0 but you can opt out of warnings for the tim
|
|
|
716
755
|
- Added `List#traverse` that "flips" the list with an embedded monad (flash-gordon + damncabbage)
|
|
717
756
|
- Added `#tee` for all right-biased monads (flash-gordon)
|
|
718
757
|
|
|
758
|
+
[0.3.0]: https://github.com/dry-rb/dry-monads/compare/v0.2.1...v0.3.0
|
|
719
759
|
|
|
720
|
-
[
|
|
721
|
-
|
|
722
|
-
## 0.2.1 2016-11-13
|
|
723
|
-
|
|
760
|
+
## [0.2.1] - 2016-11-13
|
|
724
761
|
|
|
725
762
|
### Added
|
|
726
763
|
|
|
@@ -731,32 +768,26 @@ This behavior will be dropped in 2.0 but you can opt out of warnings for the tim
|
|
|
731
768
|
- `Right(nil).to_maybe` now returns `None` with a warning instead of failing (orisaka)
|
|
732
769
|
- `Some#value_or` doesn't require an argument because `None#value_or` doesn't require it either if a block was passed (flash-gordon)
|
|
733
770
|
|
|
771
|
+
[0.2.1]: https://github.com/dry-rb/dry-monads/compare/v0.2.0...v0.2.1
|
|
734
772
|
|
|
735
|
-
[
|
|
736
|
-
|
|
737
|
-
## 0.2.0 2016-09-18
|
|
738
|
-
|
|
773
|
+
## [0.2.0] - 2016-09-18
|
|
739
774
|
|
|
740
775
|
### Added
|
|
741
776
|
|
|
742
777
|
- Added `Maybe#to_json` as an opt-in extension for serialization to JSON (rocknruby)
|
|
743
778
|
- Added `Maybe#value_or` which returns you the underlying value with a fallback in a single method call (dsounded)
|
|
744
779
|
|
|
780
|
+
[0.2.0]: https://github.com/dry-rb/dry-monads/compare/v0.1.1...v0.2.0
|
|
745
781
|
|
|
746
|
-
[
|
|
747
|
-
|
|
748
|
-
## 0.1.1 2016-08-25
|
|
749
|
-
|
|
782
|
+
## [0.1.1] - 2016-08-25
|
|
750
783
|
|
|
751
784
|
### Fixed
|
|
752
785
|
|
|
753
786
|
- Added explicit requires of `dry-equalizer`. This allows to safely load only specific monads (artofhuman)
|
|
754
787
|
|
|
788
|
+
[0.1.1]: https://github.com/dry-rb/dry-monads/compare/v0.1.0...v0.1.1
|
|
755
789
|
|
|
756
|
-
[
|
|
757
|
-
|
|
758
|
-
## 0.1.0 2016-08-23
|
|
759
|
-
|
|
790
|
+
## [0.1.0] - 2016-08-23
|
|
760
791
|
|
|
761
792
|
### Added
|
|
762
793
|
|
|
@@ -766,19 +797,17 @@ This behavior will be dropped in 2.0 but you can opt out of warnings for the tim
|
|
|
766
797
|
|
|
767
798
|
- Dropped MRI 2.0 support (flash-gordon)
|
|
768
799
|
|
|
769
|
-
[
|
|
770
|
-
|
|
771
|
-
## 0.0.2 2016-06-29
|
|
800
|
+
[0.1.0]: https://github.com/dry-rb/dry-monads/compare/v0.0.2...v0.1.0
|
|
772
801
|
|
|
802
|
+
## [0.0.2] - 2016-06-29
|
|
773
803
|
|
|
774
804
|
### Added
|
|
775
805
|
|
|
776
806
|
- Added `Either#to_either` so that you can rely on duck-typing when you work with different types of monads (timriley)
|
|
777
807
|
- Added `Maybe#to_maybe` for consistency with `#to_either` (flash-gordon)
|
|
778
808
|
|
|
809
|
+
[0.0.2]: https://github.com/dry-rb/dry-monads/compare/v0.0.1...v0.0.2
|
|
779
810
|
|
|
780
|
-
[
|
|
781
|
-
|
|
782
|
-
## 0.0.1 2016-05-02
|
|
811
|
+
## [0.0.1] - 2016-05-02
|
|
783
812
|
|
|
784
813
|
Initial release containing `Either`, `Maybe`, and `Try` monads.
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
<!---
|
|
2
|
-
[gem]: https://rubygems.org/gems/dry-monads
|
|
3
|
-
[actions]: https://github.com/dry-rb/dry-monads/actions
|
|
4
|
-
|
|
5
|
-
# dry-monads [][gem] [][actions]
|
|
1
|
+
<!--- This file is synced from hanakai-rb/repo-sync -->
|
|
6
2
|
|
|
7
|
-
|
|
3
|
+
[actions]: https://github.com/dry-rb/dry-monads/actions
|
|
4
|
+
[chat]: https://discord.gg/naQApPAsZB
|
|
5
|
+
[forum]: https://discourse.hanamirb.org
|
|
6
|
+
[rubygem]: https://rubygems.org/gems/dry-monads
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
* [API documentation](http://rubydoc.info/gems/dry-monads)
|
|
11
|
-
* [Forum](https://discourse.dry-rb.org)
|
|
8
|
+
# dry-monads [][rubygem] [][actions]
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
[][forum]
|
|
11
|
+
[][chat]
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
## Links
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
- [User documentation](https://dry-rb.org/gems/dry-monads)
|
|
16
|
+
- [API documentation](http://rubydoc.info/gems/dry-monads)
|
|
17
|
+
- [Forum](https://discourse.dry-rb.org)
|
|
19
18
|
|
|
20
19
|
## License
|
|
21
20
|
|
|
22
21
|
See `LICENSE` file.
|
|
22
|
+
|
data/dry-monads.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# This file is synced from hanakai-rb/repo-sync. To update it, edit repo-sync.yml.
|
|
4
4
|
|
|
5
5
|
lib = File.expand_path("lib", __dir__)
|
|
6
6
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
@@ -8,8 +8,8 @@ require "dry/monads/version"
|
|
|
8
8
|
|
|
9
9
|
Gem::Specification.new do |spec|
|
|
10
10
|
spec.name = "dry-monads"
|
|
11
|
-
spec.authors = ["
|
|
12
|
-
spec.email = ["
|
|
11
|
+
spec.authors = ["Hanakai team"]
|
|
12
|
+
spec.email = ["info@hanakai.org"]
|
|
13
13
|
spec.license = "MIT"
|
|
14
14
|
spec.version = Dry::Monads::VERSION.dup
|
|
15
15
|
|
|
@@ -17,20 +17,25 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
spec.description = spec.summary
|
|
18
18
|
spec.homepage = "https://dry-rb.org/gems/dry-monads"
|
|
19
19
|
spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-monads.gemspec", "lib/**/*"]
|
|
20
|
-
spec.bindir = "
|
|
21
|
-
spec.executables = []
|
|
20
|
+
spec.bindir = "exe"
|
|
21
|
+
spec.executables = Dir["exe/*"].map { |f| File.basename(f) }
|
|
22
22
|
spec.require_paths = ["lib"]
|
|
23
23
|
|
|
24
|
-
spec.
|
|
25
|
-
spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-monads/blob/main/CHANGELOG.md"
|
|
26
|
-
spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-monads"
|
|
27
|
-
spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-monads/issues"
|
|
28
|
-
spec.metadata["rubygems_mfa_required"] = "true"
|
|
24
|
+
spec.extra_rdoc_files = ["README.md", "CHANGELOG.md", "LICENSE"]
|
|
29
25
|
|
|
30
|
-
spec.
|
|
26
|
+
spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-monads/blob/main/CHANGELOG.md"
|
|
27
|
+
spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-monads"
|
|
28
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-monads/issues"
|
|
29
|
+
spec.metadata["funding_uri"] = "https://github.com/sponsors/hanami"
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
spec.
|
|
35
|
-
spec.
|
|
31
|
+
spec.required_ruby_version = ">= 3.3"
|
|
32
|
+
|
|
33
|
+
spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
|
|
34
|
+
spec.add_runtime_dependency "dry-core", "~> 1.1"
|
|
35
|
+
spec.add_runtime_dependency "zeitwerk", "~> 2.6"
|
|
36
|
+
spec.add_development_dependency "bundler"
|
|
37
|
+
spec.add_development_dependency "debug_inspector"
|
|
38
|
+
spec.add_development_dependency "rake"
|
|
39
|
+
spec.add_development_dependency "rspec"
|
|
36
40
|
end
|
|
41
|
+
|
data/lib/dry/monads/do/mixin.rb
CHANGED
data/lib/dry/monads/do.rb
CHANGED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
# Require json 2.15, the first version with everything this extension needs:
|
|
6
|
+
#
|
|
7
|
+
# - json 2.10 has `JSON::Coder`, but ignores the `on_load:` option
|
|
8
|
+
# - json 2.11 through 2.14 never pass the hash key flag to the `as_json` callback
|
|
9
|
+
#
|
|
10
|
+
# Both of these gaps are silent and may lead to incorrect serialization, so refuse to load instead.
|
|
11
|
+
if Gem::Version.new(::JSON::VERSION) < Gem::Version.new("2.15.0")
|
|
12
|
+
raise "The Dry Monads :json extension needs json 2.15.0 or later, but json #{::JSON::VERSION} is loaded"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module Dry
|
|
16
|
+
module Monads
|
|
17
|
+
# Reads and writes monads as JSON via `JSON::Coder`.
|
|
18
|
+
#
|
|
19
|
+
# This replaces the old `json/add/dry/monads/maybe` file, no longer working from json 3.0, which
|
|
20
|
+
# removed the whole `json/add` mechanism, so monads can no longer serialize via `JSON.dump` and
|
|
21
|
+
# `JSON.load` globally. A coder does the same job locally, without patching anything.
|
|
22
|
+
#
|
|
23
|
+
# The wire format remains unchanged, so JSON written by older versions still loads.
|
|
24
|
+
#
|
|
25
|
+
# @example
|
|
26
|
+
# Dry::Monads.load_extensions(:json)
|
|
27
|
+
#
|
|
28
|
+
# coder = Dry::Monads.json_coder
|
|
29
|
+
# coder.dump(Some(3)) # => %({"json_class":"Dry::Monads::Maybe::Some","value":3})
|
|
30
|
+
# coder.load(%({"json_class":"Dry::Monads::Maybe::Some","value":3})) # => Some(3)
|
|
31
|
+
#
|
|
32
|
+
# @api public
|
|
33
|
+
module JSONCoder
|
|
34
|
+
# Key used to tag a serialized monad.
|
|
35
|
+
JSON_CLASS_KEY = "json_class"
|
|
36
|
+
|
|
37
|
+
# Called for every object the generator cannot write natively.
|
|
38
|
+
#
|
|
39
|
+
# The second argument is `true` when the object is a hash key and `false` everywhere else. We
|
|
40
|
+
# do not use it, because a monad never appears as a key, but it must be accepted.
|
|
41
|
+
#
|
|
42
|
+
# @api private
|
|
43
|
+
AS_JSON = lambda { |object, *|
|
|
44
|
+
case object
|
|
45
|
+
when Maybe
|
|
46
|
+
{JSON_CLASS_KEY => object.class.name, "value" => object.none? ? nil : object.value!}
|
|
47
|
+
else
|
|
48
|
+
object
|
|
49
|
+
end
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# Called for every value the parser produces, innermost first.
|
|
53
|
+
#
|
|
54
|
+
# @api private
|
|
55
|
+
ON_LOAD = lambda { |value|
|
|
56
|
+
next value unless value.is_a?(::Hash) && value.key?(JSON_CLASS_KEY)
|
|
57
|
+
|
|
58
|
+
case value[JSON_CLASS_KEY]
|
|
59
|
+
when Maybe::Some.name then Maybe::Some.new(value["value"])
|
|
60
|
+
when Maybe::None.name then Maybe::None.instance
|
|
61
|
+
else value
|
|
62
|
+
end
|
|
63
|
+
}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Returns a coder that reads and writes monads. Unknown objects raise `JSON::GeneratorError`.
|
|
67
|
+
#
|
|
68
|
+
# A `JSON::Coder` is frozen on creation, so you cannot add monad support to an existing coder.
|
|
69
|
+
# Build your coder here instead: provide `as_json:` to write your own types, and `on_load:` to
|
|
70
|
+
# read them back. Both will run after the monad callbacks, and both see every value, so pass
|
|
71
|
+
# through anything you do not recognize.
|
|
72
|
+
#
|
|
73
|
+
# @example a coder that reads and writes monads and times
|
|
74
|
+
# coder = Dry::Monads.json_coder(
|
|
75
|
+
# as_json: ->(object, *) {
|
|
76
|
+
# object.is_a?(Time) ? {"json_class" => "Time", "value" => object.iso8601} : object
|
|
77
|
+
# },
|
|
78
|
+
# on_load: ->(value) {
|
|
79
|
+
# if value.is_a?(Hash) && value["json_class"] == "Time"
|
|
80
|
+
# Time.iso8601(value["value"])
|
|
81
|
+
# else
|
|
82
|
+
# value
|
|
83
|
+
# end
|
|
84
|
+
# }
|
|
85
|
+
# )
|
|
86
|
+
#
|
|
87
|
+
# coder.dump(Some(Time.utc(2026)))
|
|
88
|
+
# # => %({"json_class":"Dry::Monads::Maybe::Some","value":{"json_class":"Time","value":"2026-01-01T00:00:00Z"}})
|
|
89
|
+
#
|
|
90
|
+
# Monads nest inside your types and the other way around, because the generator and the
|
|
91
|
+
# parser walk the whole document and call both callbacks at every step.
|
|
92
|
+
#
|
|
93
|
+
# `as_json:` takes a second argument, which is `true` when the object is a hash key, and `false`
|
|
94
|
+
# everywhere else. Use it if you write a type that can be a key, because for a key you must
|
|
95
|
+
# return a String or a Symbol. Anything else raises `JSON::GeneratorError`:
|
|
96
|
+
#
|
|
97
|
+
# as_json: ->(object, as_key) {
|
|
98
|
+
# next object unless object.is_a?(Time)
|
|
99
|
+
# as_key ? object.iso8601 : {"json_class" => "Time", "value" => object.iso8601}
|
|
100
|
+
# }
|
|
101
|
+
#
|
|
102
|
+
# Even if you don't need this argument, your lambda must accept it (as in `->(object, *)`), or
|
|
103
|
+
# you will see an `ArgumentError` on the first dump.
|
|
104
|
+
#
|
|
105
|
+
# @param as_json [#call, nil] runs on every object the generator cannot write natively, after
|
|
106
|
+
# the monad callback
|
|
107
|
+
# @param on_load [#call, nil] runs on every parsed value, after the monad callback
|
|
108
|
+
# @param options [Hash] passed on to `JSON::Coder.new`
|
|
109
|
+
# @return [JSON::Coder]
|
|
110
|
+
#
|
|
111
|
+
# @api public
|
|
112
|
+
def self.json_coder(as_json: nil, on_load: nil, **options, &block)
|
|
113
|
+
# `JSON::Coder.new` takes its `as_json` callback as a block. We've opted to make it an keyword
|
|
114
|
+
# argument for consistency alongside `on_load:`.
|
|
115
|
+
#
|
|
116
|
+
# A user familiar with `JSON::Coder` may provide a block, so raise an error just in case.
|
|
117
|
+
raise ArgumentError, "pass the as_json callback as `as_json:`, not as a block" if block
|
|
118
|
+
|
|
119
|
+
::JSON::Coder.new(
|
|
120
|
+
on_load: on_load ? JSONCoder::ON_LOAD >> on_load : JSONCoder::ON_LOAD,
|
|
121
|
+
**options
|
|
122
|
+
) do |object, as_key|
|
|
123
|
+
json = JSONCoder::AS_JSON.call(object, as_key)
|
|
124
|
+
as_json ? as_json.call(json, as_key) : json
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -44,13 +44,14 @@ module Dry
|
|
|
44
44
|
}.freeze
|
|
45
45
|
|
|
46
46
|
PREDICATES.each do |name, args|
|
|
47
|
-
args => {
|
|
47
|
+
args => {expected_classes:, extract_value:}
|
|
48
48
|
expected_constructors = expected_classes.map(&:name).map do |c|
|
|
49
49
|
c.split("::").last
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
matcher :"be_#{name}" do |
|
|
52
|
+
matcher :"be_#{name}" do |*expected_args|
|
|
53
53
|
predicate = "#{name}?"
|
|
54
|
+
expected = expected_args.fetch(0, Undefined)
|
|
54
55
|
|
|
55
56
|
match do |actual|
|
|
56
57
|
if expected_classes.any? { |klass| actual.is_a?(klass) }
|
|
@@ -159,6 +160,37 @@ module Dry
|
|
|
159
160
|
::Dry::Monads::List
|
|
160
161
|
end
|
|
161
162
|
end
|
|
163
|
+
|
|
164
|
+
def rspec_example_context?(location)
|
|
165
|
+
example_group_instance = ::RSpec.current_example&.example_group_instance
|
|
166
|
+
return false unless example_group_instance
|
|
167
|
+
|
|
168
|
+
spec_example_block?(location) || example_group_method?(example_group_instance, location)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
private
|
|
172
|
+
|
|
173
|
+
def spec_example_block?(location)
|
|
174
|
+
location.path.end_with?("_spec.rb") && location.label.include?("block")
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def example_group_method?(example_group_instance, location)
|
|
178
|
+
method_name = caller_method_name(location)
|
|
179
|
+
return false unless method_name
|
|
180
|
+
|
|
181
|
+
owner = example_group_instance.method(method_name).owner
|
|
182
|
+
|
|
183
|
+
![::BasicObject, ::Kernel, ::Object].include?(owner)
|
|
184
|
+
rescue NameError
|
|
185
|
+
false
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def caller_method_name(location)
|
|
189
|
+
label = location.label.to_s
|
|
190
|
+
return nil if label.include?("block")
|
|
191
|
+
|
|
192
|
+
label.split(/[.#]/).last&.to_sym
|
|
193
|
+
end
|
|
162
194
|
end
|
|
163
195
|
end
|
|
164
196
|
end
|
|
@@ -185,7 +217,7 @@ catch_missing_const = Module.new do
|
|
|
185
217
|
def const_missing(name)
|
|
186
218
|
const_name = Dry::Monads::RSpec.resolve_constant_name(name)
|
|
187
219
|
|
|
188
|
-
if const_name && caller_locations(1, 1).first
|
|
220
|
+
if const_name && Dry::Monads::RSpec.rspec_example_context?(caller_locations(1, 1).first)
|
|
189
221
|
Dry::Monads::RSpec.name_to_const(const_name)
|
|
190
222
|
else
|
|
191
223
|
super
|
data/lib/dry/monads/list.rb
CHANGED
|
@@ -331,9 +331,12 @@ module Dry
|
|
|
331
331
|
#
|
|
332
332
|
# @example
|
|
333
333
|
# case List[1, 2, 3]
|
|
334
|
-
# in List[1, 2, x]
|
|
335
|
-
#
|
|
336
|
-
# in List[
|
|
334
|
+
# in List[1, 2, x]
|
|
335
|
+
# x
|
|
336
|
+
# in List[Integer, _, _]
|
|
337
|
+
# # ...
|
|
338
|
+
# in List[0..2, _, _]
|
|
339
|
+
# # ...
|
|
337
340
|
# end
|
|
338
341
|
#
|
|
339
342
|
# @api private
|
data/lib/dry/monads/maybe.rb
CHANGED
|
@@ -142,9 +142,9 @@ module Dry
|
|
|
142
142
|
def maybe(...) = Maybe.coerce(bind(...))
|
|
143
143
|
|
|
144
144
|
# Accepts a block and runs it against the wrapped value.
|
|
145
|
-
# If the block returns a
|
|
145
|
+
# If the block returns a truthy value the result is self,
|
|
146
146
|
# otherwise None. If no block is given, the value serves
|
|
147
|
-
#
|
|
147
|
+
# as its result.
|
|
148
148
|
#
|
|
149
149
|
# @param with [#call] positional block
|
|
150
150
|
# @param block [Proc] block
|
|
@@ -250,9 +250,12 @@ module Dry
|
|
|
250
250
|
#
|
|
251
251
|
# @example
|
|
252
252
|
# case Some(:foo)
|
|
253
|
-
# in Some(Integer)
|
|
254
|
-
#
|
|
255
|
-
# in
|
|
253
|
+
# in Some(Integer)
|
|
254
|
+
# # ...
|
|
255
|
+
# in Some(:bar)
|
|
256
|
+
# # ...
|
|
257
|
+
# in None()
|
|
258
|
+
# # ...
|
|
256
259
|
# end
|
|
257
260
|
#
|
|
258
261
|
# @api private
|
data/lib/dry/monads/result.rb
CHANGED
|
@@ -368,7 +368,7 @@ module Dry
|
|
|
368
368
|
class Some < Maybe
|
|
369
369
|
# Converts to Sucess(value!)
|
|
370
370
|
#
|
|
371
|
-
# @param
|
|
371
|
+
# @param _fail [#call] Fallback value
|
|
372
372
|
# @param block [Proc] Fallback block
|
|
373
373
|
# @return [Success<Any>]
|
|
374
374
|
def to_result(_fail = Unit, &) = Result::Success.new(@value)
|
|
@@ -176,9 +176,12 @@ module Dry
|
|
|
176
176
|
#
|
|
177
177
|
# @example
|
|
178
178
|
# case Success(x)
|
|
179
|
-
# in Success(Integer)
|
|
180
|
-
#
|
|
181
|
-
# in Success(2..
|
|
179
|
+
# in Success(Integer)
|
|
180
|
+
# # ...
|
|
181
|
+
# in Success(2..100)
|
|
182
|
+
# # ...
|
|
183
|
+
# in Success(2..200 => code)
|
|
184
|
+
# # ...
|
|
182
185
|
# end
|
|
183
186
|
#
|
|
184
187
|
# @api private
|
|
@@ -322,10 +325,14 @@ module Dry
|
|
|
322
325
|
#
|
|
323
326
|
# @example
|
|
324
327
|
# case Success(x)
|
|
325
|
-
# in Success(Integer)
|
|
326
|
-
#
|
|
327
|
-
# in Success(2..
|
|
328
|
-
#
|
|
328
|
+
# in Success(Integer)
|
|
329
|
+
# # ...
|
|
330
|
+
# in Success(2..100)
|
|
331
|
+
# # ...
|
|
332
|
+
# in Success(2..200 => code)
|
|
333
|
+
# # ...
|
|
334
|
+
# in Failure(_)
|
|
335
|
+
# # ...
|
|
329
336
|
# end
|
|
330
337
|
#
|
|
331
338
|
# @api private
|
data/lib/dry/monads/task.rb
CHANGED
|
@@ -140,7 +140,7 @@ module Dry
|
|
|
140
140
|
end
|
|
141
141
|
alias_method :inspect, :to_s
|
|
142
142
|
|
|
143
|
-
#
|
|
143
|
+
# Transforms the error if the computation wasn't successful.
|
|
144
144
|
#
|
|
145
145
|
# @param block [Proc]
|
|
146
146
|
# @return [Task]
|
|
@@ -161,8 +161,8 @@ module Dry
|
|
|
161
161
|
inner.execute
|
|
162
162
|
inner.on_success { child.on_fulfill(_1) }
|
|
163
163
|
inner.on_error { child.on_reject(_1) }
|
|
164
|
-
rescue StandardError =>
|
|
165
|
-
child.on_reject(
|
|
164
|
+
rescue StandardError => exception
|
|
165
|
+
child.on_reject(exception)
|
|
166
166
|
end
|
|
167
167
|
promise.on_success { child.on_fulfill(_1) }
|
|
168
168
|
|
data/lib/dry/monads/try.rb
CHANGED
|
@@ -27,8 +27,8 @@ module Dry
|
|
|
27
27
|
# @return [Try::Value, Try::Error]
|
|
28
28
|
def run(exceptions, f)
|
|
29
29
|
Value.new(exceptions, f.call)
|
|
30
|
-
rescue *exceptions =>
|
|
31
|
-
Error.new(
|
|
30
|
+
rescue *exceptions => exception
|
|
31
|
+
Error.new(exception)
|
|
32
32
|
end
|
|
33
33
|
deprecate :lift, :run
|
|
34
34
|
|
|
@@ -125,8 +125,8 @@ module Dry
|
|
|
125
125
|
# @return [Object, Try::Error]
|
|
126
126
|
def bind(...)
|
|
127
127
|
super
|
|
128
|
-
rescue *catchable =>
|
|
129
|
-
Error.new(
|
|
128
|
+
rescue *catchable => exception
|
|
129
|
+
Error.new(exception)
|
|
130
130
|
end
|
|
131
131
|
|
|
132
132
|
# Does the same thing as #bind except it also wraps the value
|
|
@@ -143,8 +143,8 @@ module Dry
|
|
|
143
143
|
# @return [Try::Value, Try::Error]
|
|
144
144
|
def fmap(...)
|
|
145
145
|
Value.new(catchable, bind_call(...))
|
|
146
|
-
rescue *catchable =>
|
|
147
|
-
Error.new(
|
|
146
|
+
rescue *catchable => exception
|
|
147
|
+
Error.new(exception)
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
# @return [String]
|
|
@@ -159,7 +159,7 @@ module Dry
|
|
|
159
159
|
|
|
160
160
|
# Ignores values and returns self, see {Try::Error#recover}
|
|
161
161
|
#
|
|
162
|
-
# @param
|
|
162
|
+
# @param _errors [Class] List of Exception subclasses
|
|
163
163
|
#
|
|
164
164
|
# @return [Try::Value]
|
|
165
165
|
def recover(*_errors, &) = self
|
data/lib/dry/monads/unit.rb
CHANGED
data/lib/dry/monads/validated.rb
CHANGED
|
@@ -46,7 +46,7 @@ module Dry
|
|
|
46
46
|
def bind(...)
|
|
47
47
|
# See https://typelevel.org/cats/datatypes/validated.html for details on why
|
|
48
48
|
raise NotImplementedError,
|
|
49
|
-
|
|
49
|
+
"Validated is not a monad because it would violate the monad laws"
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# Valid result
|
data/lib/dry/monads/version.rb
CHANGED
data/lib/dry/monads.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dry-monads
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
bindir: bin
|
|
7
|
+
- Hanakai team
|
|
8
|
+
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: concurrent-ruby
|
|
@@ -52,12 +51,71 @@ dependencies:
|
|
|
52
51
|
- - "~>"
|
|
53
52
|
- !ruby/object:Gem::Version
|
|
54
53
|
version: '2.6'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: bundler
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: debug_inspector
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rake
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: rspec
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
55
110
|
description: Common monads for Ruby
|
|
56
111
|
email:
|
|
57
|
-
-
|
|
112
|
+
- info@hanakai.org
|
|
58
113
|
executables: []
|
|
59
114
|
extensions: []
|
|
60
|
-
extra_rdoc_files:
|
|
115
|
+
extra_rdoc_files:
|
|
116
|
+
- CHANGELOG.md
|
|
117
|
+
- LICENSE
|
|
118
|
+
- README.md
|
|
61
119
|
files:
|
|
62
120
|
- CHANGELOG.md
|
|
63
121
|
- LICENSE
|
|
@@ -74,6 +132,7 @@ files:
|
|
|
74
132
|
- lib/dry/monads/do/mixin.rb
|
|
75
133
|
- lib/dry/monads/errors.rb
|
|
76
134
|
- lib/dry/monads/extensions.rb
|
|
135
|
+
- lib/dry/monads/extensions/json.rb
|
|
77
136
|
- lib/dry/monads/extensions/pretty_print.rb
|
|
78
137
|
- lib/dry/monads/extensions/rspec.rb
|
|
79
138
|
- lib/dry/monads/extensions/super_diff.rb
|
|
@@ -91,17 +150,14 @@ files:
|
|
|
91
150
|
- lib/dry/monads/unit.rb
|
|
92
151
|
- lib/dry/monads/validated.rb
|
|
93
152
|
- lib/dry/monads/version.rb
|
|
94
|
-
- lib/json/add/dry/monads/maybe.rb
|
|
95
153
|
homepage: https://dry-rb.org/gems/dry-monads
|
|
96
154
|
licenses:
|
|
97
155
|
- MIT
|
|
98
156
|
metadata:
|
|
99
|
-
allowed_push_host: https://rubygems.org
|
|
100
157
|
changelog_uri: https://github.com/dry-rb/dry-monads/blob/main/CHANGELOG.md
|
|
101
158
|
source_code_uri: https://github.com/dry-rb/dry-monads
|
|
102
159
|
bug_tracker_uri: https://github.com/dry-rb/dry-monads/issues
|
|
103
|
-
|
|
104
|
-
post_install_message:
|
|
160
|
+
funding_uri: https://github.com/sponsors/hanami
|
|
105
161
|
rdoc_options: []
|
|
106
162
|
require_paths:
|
|
107
163
|
- lib
|
|
@@ -109,15 +165,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
109
165
|
requirements:
|
|
110
166
|
- - ">="
|
|
111
167
|
- !ruby/object:Gem::Version
|
|
112
|
-
version: 3.
|
|
168
|
+
version: '3.3'
|
|
113
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
170
|
requirements:
|
|
115
171
|
- - ">="
|
|
116
172
|
- !ruby/object:Gem::Version
|
|
117
173
|
version: '0'
|
|
118
174
|
requirements: []
|
|
119
|
-
rubygems_version: 3.
|
|
120
|
-
signing_key:
|
|
175
|
+
rubygems_version: 3.6.9
|
|
121
176
|
specification_version: 4
|
|
122
177
|
summary: Common monads for Ruby
|
|
123
178
|
test_files: []
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: false
|
|
2
|
-
|
|
3
|
-
require "json" unless defined?(JSON::JSON_LOADED) && JSON::JSON_LOADED
|
|
4
|
-
|
|
5
|
-
require "dry/monads"
|
|
6
|
-
|
|
7
|
-
# Inspired by standard library implementation
|
|
8
|
-
# for Time serialization/deserialization see (json/lib/json/add/time.rb)
|
|
9
|
-
#
|
|
10
|
-
module Dry
|
|
11
|
-
module Monads
|
|
12
|
-
class Maybe
|
|
13
|
-
# Deserializes JSON string by using Dry::Monads::Maybe#lift method
|
|
14
|
-
def self.json_create(serialized)
|
|
15
|
-
coerce(serialized.fetch("value"))
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# Returns a hash, that will be turned into a JSON object and represent this
|
|
19
|
-
# object.
|
|
20
|
-
def as_json(*, **)
|
|
21
|
-
{
|
|
22
|
-
JSON.create_id => self.class.name,
|
|
23
|
-
value: none? ? nil : @value
|
|
24
|
-
}
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Stores class name (Dry::Monads::Maybe::Some or Dry::Monads::Maybe::None)
|
|
28
|
-
# with the monad value as JSON string
|
|
29
|
-
def to_json(...) = as_json.to_json(...)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|