monad-oxide 0.1.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.
Files changed (5) hide show
  1. checksums.yaml +7 -0
  2. data/lib/err_spec.rb +300 -0
  3. data/lib/ok_spec.rb +347 -0
  4. data/lib/result_spec.rb +30 -0
  5. metadata +77 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 504855112b6ed7faeb0c45305ed117f1e9950af5cbba9739680e493633ce0b84
4
+ data.tar.gz: 79491d6d8191a267e64a1fe55f00ef6899d49496a654d9458382b09d40f76f7a
5
+ SHA512:
6
+ metadata.gz: 3c186a75ca88ae69c1d6fa2e17ad7f7963177a8e6aa28aecf6457c2b549aa4a6ac6c6acb6161b017f0e58d8367f5728bcac032a8e34a82caeadf5ef9d3824e37
7
+ data.tar.gz: e36391798ab39c82c941b463688cbca7eee416d8d720d7be0eeb428d336b4456ab236fe666b8d80db15a42f1068d3c0466dcc6d24e4b30678edc799e303e6f3f
data/lib/err_spec.rb ADDED
@@ -0,0 +1,300 @@
1
+ require 'monad-oxide'
2
+ require 'ok'
3
+ require 'err'
4
+
5
+ describe MonadOxide::Err do
6
+
7
+ # The constructor tests (MonadOxide::Err.new()) are exactly the same as the
8
+ # helper (MonadOxide.err()).
9
+ ctor_tests = ->(ctor) {
10
+ it 'raises a TypeError if not provided an Exception' do
11
+ expect { ctor.call('foo') }.to raise_error(TypeError)
12
+ end
13
+
14
+ it 'establishes a backtrace for unraised Exceptions' do
15
+ expect(
16
+ ctor.call(StandardError.new('foo'))
17
+ .unwrap_err()
18
+ .backtrace()
19
+ ).not_to(be_nil())
20
+ end
21
+
22
+ it 'retains backtraces for raised Exceptions' do
23
+ begin
24
+ raise StandardError.new('foo')
25
+ rescue => e
26
+ expect(
27
+ ctor.call(e)
28
+ .unwrap_err()
29
+ .backtrace()
30
+ ).to(be(e.backtrace()))
31
+ end
32
+ end
33
+ }
34
+
35
+ context '#initialize' do
36
+ ctor_tests.call(MonadOxide::Err.method(:new))
37
+ end
38
+
39
+ context 'MonadOxide.err' do
40
+ ctor_tests.call(MonadOxide.method(:err))
41
+ end
42
+
43
+ context '#and_then' do
44
+
45
+ context 'with blocks' do
46
+ it 'does nothing with the block' do
47
+ effected = 'unset'
48
+ MonadOxide.err(StandardError.new('foo'))
49
+ .and_then() {|s| effected = "effect: #{s}"}
50
+ expect(effected).not_to(eq('effect: foo'))
51
+ end
52
+
53
+ it 'does not change the underlying data' do
54
+ expect(
55
+ MonadOxide.err(StandardError.new('foo'))
56
+ .and_then() { 'bar' }
57
+ .unwrap_err()
58
+ .message()
59
+ ).to(eq('foo'))
60
+ end
61
+ end
62
+
63
+ context 'with Procs' do
64
+ it 'does nothing with the function' do
65
+ effected = 'unset'
66
+ MonadOxide.err(StandardError.new('foo'))
67
+ .and_then(->(s) { effected = "effect: #{s}"})
68
+ expect(effected).not_to(eq('effect: foo'))
69
+ end
70
+
71
+ it 'does not change the underlying data' do
72
+ expect(
73
+ MonadOxide.err(StandardError.new('foo'))
74
+ .and_then(->(_) { 'bar' })
75
+ .unwrap_err()
76
+ .message()
77
+ ).to(eq('foo'))
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+
84
+ context '#inspect_err' do
85
+ context 'with blocks' do
86
+ it 'applies the data to the block provided' do
87
+ effected = 'unset'
88
+ MonadOxide.err(StandardError.new('foo'))
89
+ .inspect_err(->(s) { effected = "effect: #{s}"})
90
+ expect(effected).to(eq('effect: foo'))
91
+ end
92
+
93
+ it 'does not change the underlying data' do
94
+ expect(
95
+ MonadOxide.err(StandardError.new('foo'))
96
+ .inspect_err() {|_| 'bar' }
97
+ .unwrap_err()
98
+ .message()
99
+ ).to(eq('foo'))
100
+ end
101
+
102
+ it 'returns an Err with the error from the block' do
103
+ expect(
104
+ MonadOxide.err(StandardError.new('foo'))
105
+ .inspect_err() {|_| raise StandardError.new('flagrant') }
106
+ .unwrap_err()
107
+ .message()
108
+ ).to(eq('flagrant'))
109
+ end
110
+ end
111
+
112
+ context 'with Procs' do
113
+ it 'applies the data to the function provided' do
114
+ effected = 'unset'
115
+ MonadOxide.err(StandardError.new('foo'))
116
+ .inspect_err(->(s) { effected = "effect: #{s}"})
117
+ expect(effected).to(eq('effect: foo'))
118
+ end
119
+
120
+ it 'does not change the underlying data' do
121
+ expect(
122
+ MonadOxide.err(StandardError.new('foo'))
123
+ .inspect_err(->(_) { 'bar' })
124
+ .unwrap_err()
125
+ .message()
126
+ ).to(eq('foo'))
127
+ end
128
+
129
+ it 'returns an Err with the error from the function' do
130
+ expect(
131
+ MonadOxide.err(StandardError.new('foo'))
132
+ .inspect_err(->(_) { raise StandardError.new('flagrant') })
133
+ .unwrap_err()
134
+ .message()
135
+ ).to(eq('flagrant'))
136
+ end
137
+ end
138
+ end
139
+
140
+ context '#inspect_ok' do
141
+ context 'with blocks' do
142
+ it 'does nothing with the block' do
143
+ effected = 'unset'
144
+ MonadOxide.err(StandardError.new('foo'))
145
+ .inspect_ok() {|s| effected = "effect: #{s}"}
146
+ expect(effected).not_to(eq('effect: foo'))
147
+ end
148
+
149
+ it 'does not change the underlying data' do
150
+ expect(
151
+ MonadOxide.err(StandardError.new('foo'))
152
+ .inspect_ok() { 'bar' }
153
+ .unwrap_err()
154
+ .message()
155
+ ).to(eq('foo'))
156
+ end
157
+ end
158
+
159
+ context 'with Procs' do
160
+ it 'does nothing with the function' do
161
+ effected = 'unset'
162
+ MonadOxide.err(StandardError.new('foo'))
163
+ .inspect_ok(->(s) { effected = "effect: #{s}"})
164
+ expect(effected).not_to(eq('effect: foo'))
165
+ end
166
+
167
+ it 'does not change the underlying data' do
168
+ expect(
169
+ MonadOxide.err(StandardError.new('foo'))
170
+ .inspect_ok(->(_) { 'bar' })
171
+ .unwrap_err()
172
+ .message()
173
+ ).to(eq('foo'))
174
+ end
175
+ end
176
+ end
177
+
178
+
179
+ context '#map' do
180
+ context 'with blocks' do
181
+ it 'does nothing with the block' do
182
+ effected = 'unset'
183
+ MonadOxide.err(StandardError.new('foo'))
184
+ .map() {|s| effected = "effect: #{s}"}
185
+ expect(effected).not_to(eq('effect: foo'))
186
+ end
187
+
188
+ it 'does not change the underlying data' do
189
+ expect(
190
+ MonadOxide.err(StandardError.new('foo'))
191
+ .map() { 'bar' }
192
+ .unwrap_err()
193
+ .message()
194
+ ).to(eq('foo'))
195
+ end
196
+ end
197
+
198
+ context 'with Procs' do
199
+ it 'does nothing with the function' do
200
+ effected = 'unset'
201
+ MonadOxide.err(StandardError.new('foo'))
202
+ .map(->(s) { effected = "effect: #{s}"})
203
+ expect(effected).not_to(eq('effect: foo'))
204
+ end
205
+
206
+ it 'does not change the underlying data' do
207
+ expect(
208
+ MonadOxide.err(StandardError.new('foo'))
209
+ .map(->(_) { 'bar' })
210
+ .unwrap_err()
211
+ .message()
212
+ ).to(eq('foo'))
213
+ end
214
+ end
215
+ end
216
+
217
+ context '#map_err' do
218
+ context 'with blocks' do
219
+ it 'returns an Err if an error is raised in the block' do
220
+ expect(
221
+ MonadOxide.err(StandardError.new('foo'))
222
+ .map_err() {|_| raise StandardError.new('bar') }
223
+ .unwrap_err()
224
+ .message()
225
+ ).to(eq('bar'))
226
+ end
227
+
228
+ it 'returns a new Err' do
229
+ expect(
230
+ MonadOxide.err(StandardError.new('foo'))
231
+ .map_err() {|_| StandardErr.new('bar') }
232
+ .class()
233
+ ).to(be(MonadOxide::Err))
234
+ end
235
+
236
+ it 'applies the block to the data for the new Ok' do
237
+ expect(
238
+ MonadOxide.err(StandardError.new('foo'))
239
+ .map_err() {|e| StandardError.new(e.message() + 'bar') }
240
+ .unwrap_err()
241
+ .message()
242
+ ).to(eq('foobar'))
243
+ end
244
+
245
+ it 'requires the mapped value is an Exception still' do
246
+ expect(
247
+ MonadOxide.err(StandardError.new('foo'))
248
+ .map_err() {|_| 'bar'}
249
+ .unwrap_err()
250
+ .class()
251
+ ).to(be(TypeError))
252
+ end
253
+ end
254
+
255
+ context 'with Procs' do
256
+ it 'returns an Err if an error is raised in the function' do
257
+ expect(
258
+ MonadOxide.err(StandardError.new('foo'))
259
+ .map_err(->(_) { raise StandardError.new })
260
+ .unwrap_err()
261
+ .class()
262
+ ).to(be(StandardError))
263
+ end
264
+
265
+ it 'applies the function to the data for the new Ok' do
266
+ expect(
267
+ MonadOxide.err(StandardError.new('foo'))
268
+ .map_err(->(e) { StandardError.new(e.message() + 'bar') })
269
+ .unwrap_err()
270
+ .message()
271
+ ).to(eq('foobar'))
272
+ end
273
+
274
+ it 'requires the mapped value is an Exception still' do
275
+ expect(
276
+ MonadOxide.err(StandardError.new('foo'))
277
+ .map_err(->(_) { 'bar' })
278
+ .unwrap_err()
279
+ .class()
280
+ ).to(be(TypeError))
281
+ end
282
+ end
283
+ end
284
+
285
+ context '#unwrap' do
286
+ it 'raises an UnwrapError' do
287
+ expect {
288
+ MonadOxide.err(StandardError.new('foo')).unwrap()
289
+ }.to(raise_error(MonadOxide::UnwrapError))
290
+ end
291
+ end
292
+
293
+ context '#unwrap_err' do
294
+ it 'provides the underlying value' do
295
+ expect(
296
+ MonadOxide.err(StandardError.new('foo')).unwrap_err().message(),
297
+ ).to(eq('foo'))
298
+ end
299
+ end
300
+ end
data/lib/ok_spec.rb ADDED
@@ -0,0 +1,347 @@
1
+ require 'monad-oxide'
2
+ require 'ok'
3
+ require 'err'
4
+
5
+ describe MonadOxide::Ok do
6
+
7
+ context '#and_then' do
8
+
9
+ context 'with blocks' do
10
+ it 'passes the data from the Ok to the block' do
11
+ expect(
12
+ MonadOxide.ok('foo')
13
+ .and_then() {|s| MonadOxide.ok(s + 'bar') }
14
+ .unwrap()
15
+ ).to(eq('foobar'))
16
+ end
17
+
18
+ it 'converts to an Err if the block raises an error' do
19
+ expect(
20
+ MonadOxide.ok('foo')
21
+ .and_then() {|_| raise StandardError.new('flagrant') }
22
+ .class
23
+ ).to(be(MonadOxide::Err))
24
+ end
25
+
26
+ it 'converts to an Err if the block returns a non-Result' do
27
+ expect(
28
+ MonadOxide.ok('foo')
29
+ .and_then() {|_| 'bar' }
30
+ .class()
31
+ ).to(be(MonadOxide::Err))
32
+ end
33
+
34
+ it 'provides a ResultReturnExpectedError in the Err for non-Result returns' do
35
+ expect(
36
+ MonadOxide.ok('foo')
37
+ .and_then() {|_| 'bar' }
38
+ .unwrap_err()
39
+ .class()
40
+ ).to(be(MonadOxide::ResultReturnExpectedError))
41
+ end
42
+
43
+ it 'returns the same Ok returned by the block' do
44
+ expect(
45
+ MonadOxide.ok('foo')
46
+ .and_then() {|_| MonadOxide.ok('bar') }
47
+ .unwrap()
48
+ ).to(eq('bar'))
49
+ end
50
+
51
+ it 'returns the same Err returned by the block' do
52
+ expect(
53
+ MonadOxide.ok('foo')
54
+ .and_then() {|_| MonadOxide.err(StandardError.new()) }
55
+ .unwrap_err()
56
+ .class()
57
+ ).to(be(StandardError))
58
+ end
59
+ end
60
+
61
+ context 'with Procs' do
62
+ it 'passes the data from the Ok to the function' do
63
+ expect(
64
+ MonadOxide.ok('foo')
65
+ .and_then(->(s) { MonadOxide.ok(s + 'bar') })
66
+ .unwrap()
67
+ ).to(eq('foobar'))
68
+ end
69
+
70
+ it 'converts to an Err if the function raises an error' do
71
+ expect(
72
+ MonadOxide.ok('foo')
73
+ .and_then(->(_) { raise StandardError.new('flagrant') })
74
+ .class
75
+ ).to(be(MonadOxide::Err))
76
+ end
77
+
78
+ it 'converts to an Err if the function returns a non-Result' do
79
+ expect(
80
+ MonadOxide.ok('foo')
81
+ .and_then(->(_) { 'bar' })
82
+ .class()
83
+ ).to(be(MonadOxide::Err))
84
+ end
85
+
86
+ it 'provides a ResultReturnExpectedError in the Err for non-Result returns' do
87
+ expect(
88
+ MonadOxide.ok('foo')
89
+ .and_then(->(_) { 'bar' })
90
+ .unwrap_err()
91
+ .class()
92
+ ).to(be(MonadOxide::ResultReturnExpectedError))
93
+ end
94
+
95
+ it 'returns the same Ok returned by the function' do
96
+ expect(
97
+ MonadOxide.ok('foo')
98
+ .and_then(->(_) { MonadOxide.ok('bar') })
99
+ .unwrap()
100
+ ).to(eq('bar'))
101
+ end
102
+
103
+ it 'returns the same Err returned by the function' do
104
+ expect(
105
+ MonadOxide.ok('foo')
106
+ .and_then(->(_) { MonadOxide.err(StandardError.new()) })
107
+ .unwrap_err()
108
+ .class()
109
+ ).to(be(StandardError))
110
+ end
111
+
112
+ end
113
+
114
+ end
115
+
116
+ context '#map' do
117
+ context 'with blocks' do
118
+ it 'returns an Err if an error is raised in the block' do
119
+ expect(
120
+ MonadOxide.ok('foo')
121
+ .map() {|_| raise StandardError.new('bar') }
122
+ .unwrap_err()
123
+ .class()
124
+ ).to(be(StandardError))
125
+ end
126
+
127
+ it 'returns a new Ok' do
128
+ expect(
129
+ MonadOxide.ok('foo')
130
+ .map() {|_| 'bar' }
131
+ .class()
132
+ ).to(be(MonadOxide::Ok))
133
+ end
134
+
135
+ it 'applies the block to the data for the new Ok' do
136
+ expect(
137
+ MonadOxide.ok('foo')
138
+ .map() {|s| s + 'bar' }
139
+ .unwrap()
140
+ ).to(eq('foobar'))
141
+ end
142
+
143
+ it 'allows nesting of Ok' do
144
+ expect(
145
+ MonadOxide.ok('foo')
146
+ .map() {|s| MonadOxide.ok(s) }
147
+ .unwrap()
148
+ .class()
149
+ ).to(be(MonadOxide::Ok))
150
+ end
151
+
152
+ it 'allows nesting of Err' do
153
+ expect(
154
+ MonadOxide.ok('foo')
155
+ .map() {|_| MonadOxide.err(StandardError.new('bar')) }
156
+ .unwrap()
157
+ .class()
158
+ ).to(be(MonadOxide::Err))
159
+ end
160
+ end
161
+
162
+ context 'with Procs' do
163
+ it 'returns an Err if an error is raised in the function' do
164
+ expect(
165
+ MonadOxide.ok('foo')
166
+ .map(->(_) { raise StandardError.new })
167
+ .unwrap_err()
168
+ .class()
169
+ ).to(be(StandardError))
170
+ end
171
+
172
+ it 'returns a new Ok' do
173
+ expect(
174
+ MonadOxide.ok('foo')
175
+ .map(->(_) { 'bar' })
176
+ .class()
177
+ ).to(be(MonadOxide::Ok))
178
+ end
179
+
180
+ it 'applies the function to the data for the new Ok' do
181
+ expect(
182
+ MonadOxide.ok('foo')
183
+ .map(->(s) { s + 'bar' })
184
+ .unwrap()
185
+ ).to(eq('foobar'))
186
+ end
187
+
188
+ it 'allows nesting of Ok' do
189
+ expect(
190
+ MonadOxide.ok('foo')
191
+ .map(->(s) { MonadOxide.ok(s) })
192
+ .unwrap()
193
+ .class()
194
+ ).to(be(MonadOxide::Ok))
195
+ end
196
+
197
+ it 'allows nesting of Err' do
198
+ expect(
199
+ MonadOxide.ok('foo')
200
+ .map(->(_) { MonadOxide.err(StandardError.new()) })
201
+ .unwrap()
202
+ .class()
203
+ ).to(be(MonadOxide::Err))
204
+ end
205
+ end
206
+ end
207
+
208
+ context '#map_err' do
209
+ context 'with blocks' do
210
+ it 'does nothing with the block' do
211
+ effected = 'unset'
212
+ MonadOxide.ok('foo')
213
+ .map_err() {|s| effected = "effect: #{s}"}
214
+ expect(effected).not_to(eq('effect: foo'))
215
+ end
216
+
217
+ it 'does not change the underlying data' do
218
+ expect(
219
+ MonadOxide.ok('foo')
220
+ .map_err() { 'bar' }
221
+ .unwrap()
222
+ ).to(eq('foo'))
223
+ end
224
+ end
225
+
226
+ context 'with Procs' do
227
+ it 'does nothing with the function' do
228
+ effected = 'unset'
229
+ MonadOxide.ok('foo')
230
+ .map_err(->(s) { effected = "effect: #{s}"})
231
+ expect(effected).not_to(eq('effect: foo'))
232
+ end
233
+
234
+ it 'does not change the underlying data' do
235
+ expect(
236
+ MonadOxide.ok('foo')
237
+ .map_err(->(_) { 'bar' })
238
+ .unwrap()
239
+ ).to(eq('foo'))
240
+ end
241
+ end
242
+ end
243
+
244
+ context '#inspect_err' do
245
+ context 'with blocks' do
246
+ it 'does nothing with the block' do
247
+ effected = 'unset'
248
+ MonadOxide.ok('foo')
249
+ .inspect_err() {|s| effected = "effect: #{s}"}
250
+ expect(effected).not_to(eq('effect: foo'))
251
+ end
252
+
253
+ it 'does not change the underlying data' do
254
+ expect(
255
+ MonadOxide.ok('foo')
256
+ .inspect_err() { 'bar' }
257
+ .unwrap()
258
+ ).to(eq('foo'))
259
+ end
260
+ end
261
+
262
+ context 'with Procs' do
263
+ it 'does nothing with the function' do
264
+ effected = 'unset'
265
+ MonadOxide.ok('foo')
266
+ .inspect_err(->(s) { effected = "effect: #{s}"})
267
+ expect(effected).not_to(eq('effect: foo'))
268
+ end
269
+
270
+ it 'does not change the underlying data' do
271
+ expect(
272
+ MonadOxide.ok('foo')
273
+ .inspect_err(->(_) { 'bar' })
274
+ .unwrap()
275
+ ).to(eq('foo'))
276
+ end
277
+ end
278
+ end
279
+
280
+ context '#inspect_ok' do
281
+ context 'with blocks' do
282
+ it 'applies the data to the block provided' do
283
+ effected = 'unset'
284
+ MonadOxide.ok('foo')
285
+ .inspect_ok(->(s) { effected = "effect: #{s}"})
286
+ expect(effected).to(eq('effect: foo'))
287
+ end
288
+
289
+ it 'does not change the underlying data' do
290
+ expect(
291
+ MonadOxide.ok('foo')
292
+ .inspect_ok() {|_| 'bar' }
293
+ .unwrap()
294
+ ).to(eq('foo'))
295
+ end
296
+
297
+ it 'returns an Err with the error from the block' do
298
+ expect(
299
+ MonadOxide.ok('foo')
300
+ .inspect_ok() {|_| raise StandardError.new('flagrant') }
301
+ .unwrap_err()
302
+ .class()
303
+ ).to(be(StandardError))
304
+ end
305
+ end
306
+
307
+ context 'with Procs' do
308
+ it 'applies the data to the function provided' do
309
+ effected = 'unset'
310
+ MonadOxide.ok('foo')
311
+ .inspect_ok(->(s) { effected = "effect: #{s}"})
312
+ expect(effected).to(eq('effect: foo'))
313
+ end
314
+
315
+ it 'does not change the underlying data' do
316
+ expect(
317
+ MonadOxide.ok('foo')
318
+ .inspect_ok(->(_) { 'bar' })
319
+ .unwrap()
320
+ ).to(eq('foo'))
321
+ end
322
+
323
+ it 'returns an Err with the error from the function' do
324
+ expect(
325
+ MonadOxide.ok('foo')
326
+ .inspect_ok(->(_) { raise StandardError.new('flagrant') })
327
+ .unwrap_err()
328
+ .class()
329
+ ).to(be(StandardError))
330
+ end
331
+ end
332
+ end
333
+
334
+ context '#unwrap' do
335
+ it 'provides the underlying value' do
336
+ expect(MonadOxide.ok('foo').unwrap()).to(eq('foo'))
337
+ end
338
+ end
339
+
340
+ context '#unwrap_err' do
341
+ it 'raises an UnwrapError' do
342
+ expect {
343
+ MonadOxide.ok('foo').unwrap_err()
344
+ }.to(raise_error(MonadOxide::UnwrapError))
345
+ end
346
+ end
347
+ end
@@ -0,0 +1,30 @@
1
+ require 'monad-oxide'
2
+ require 'result'
3
+
4
+ describe MonadOxide::Result do
5
+ context '#initialize' do
6
+ it 'is protected from external consumption' do
7
+ expect { MonadOxide::Result.new('hi') }.to(raise_exception(NoMethodError))
8
+ end
9
+ end
10
+
11
+ context '#flatten' do
12
+ it 'returns itself when the Result is already flat' do
13
+ r = MonadOxide.ok('flat')
14
+ expect(r.flatten()).to(be(r))
15
+ end
16
+
17
+ it 'returns the inner result' do
18
+ inner = MonadOxide.ok('inner')
19
+ outer = MonadOxide.ok(inner)
20
+ expect(outer.flatten()).to(be(inner))
21
+ end
22
+
23
+ it 'returns the innermost result regardless of nesting' do
24
+ innermost = MonadOxide.ok('innermost')
25
+ inner = MonadOxide.ok(innermost)
26
+ outer = MonadOxide.ok(inner)
27
+ expect(outer.flatten()).to(be(innermost))
28
+ end
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: monad-oxide
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Logan Barnett
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-07-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: |
42
+ Monad-Oxide is a port of Rust's built-in monads from std, such as Result and
43
+ Option. This enables better reasoning about error handling and possibly missing
44
+ data.
45
+ email:
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - lib/err_spec.rb
51
+ - lib/ok_spec.rb
52
+ - lib/result_spec.rb
53
+ homepage:
54
+ licenses:
55
+ - Apache-2.0
56
+ - MIT
57
+ metadata: {}
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 2.7.0
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubygems_version: 3.1.6
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: Ruby port of Rust's Result and Option.
77
+ test_files: []