monad-oxide 0.3.0 → 0.5.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/lib/array.rb +28 -0
- data/lib/err.rb +36 -21
- data/lib/monad-oxide.rb +1 -0
- data/lib/result.rb +45 -25
- data/lib/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb1f3b4527006d3ab2dac1f0bd4f4a34ba51b5322be9f399b8aac2c329a0522f
|
4
|
+
data.tar.gz: cea1e0e146c40f451d1cfacf37b8c00b588bbd54b45426a1ba2d6b66e7a51017
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6e010dd7e59da9bc9041079e58e75b4c6de45dfb4628489023720d637c963d773a1e98890e5ed83c133ae38608cd3f2454cb64f44551a93e93a4ed91a031215
|
7
|
+
data.tar.gz: 7f51e98348f6f5588b2d57bbf6ad998c63d84a36aab3b9fd4de953766c70b968c779aa7ceeb5d3f338cab7c30924a20f39f861810756ad58d3a18f51b2e7b767
|
data/lib/array.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Reopen Array to add some handy capabilities idoimatic to Ruby.
|
2
|
+
class Array
|
3
|
+
|
4
|
+
##
|
5
|
+
# Take an Array of Results and convert them to a single Result whose value is
|
6
|
+
# an Array of Ok or Err values. Ok Results will have only Ok values, and Err
|
7
|
+
# Results will have only Err values. A single Err in the input Array will
|
8
|
+
# convert the entire Result into an Err.
|
9
|
+
#
|
10
|
+
# @return [MonadOxide::Result<Array<V>, Array<E>>] A Result whose value is an
|
11
|
+
# array of all of the Oks or Errs in the Array.
|
12
|
+
def into_result()
|
13
|
+
tracker = {
|
14
|
+
oks: [],
|
15
|
+
errs: [],
|
16
|
+
}
|
17
|
+
self.each do |result|
|
18
|
+
result.match({
|
19
|
+
MonadOxide::Ok => ->(x) { tracker[:oks].push(x) },
|
20
|
+
MonadOxide::Err => ->(e) { tracker[:errs].push(e) },
|
21
|
+
})
|
22
|
+
end
|
23
|
+
tracker[:errs].empty?() ?
|
24
|
+
MonadOxide.ok(tracker[:oks]) :
|
25
|
+
MonadOxide.err(tracker[:errs])
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
data/lib/err.rb
CHANGED
@@ -6,6 +6,33 @@ module MonadOxide
|
|
6
6
|
# Any methods in Result that would process a successful Result (Ok) will fall
|
7
7
|
# through with Err instances.
|
8
8
|
class Err < Result
|
9
|
+
|
10
|
+
##
|
11
|
+
# Add a backtrace to an Exception, or just pass long whatever was given.
|
12
|
+
# The Exception is mutated in the process.
|
13
|
+
#
|
14
|
+
# Ruby Exceptions do not come with a backtrace. During the act of raising
|
15
|
+
# an Exception, that Exception is granted a backtrace. So any kind of
|
16
|
+
# `Exception.new()' invocations will have a `nil' value for `backtrace()'.
|
17
|
+
# To get around this, we can simply raise the Exception here, and then we
|
18
|
+
# get the backtrace we want.
|
19
|
+
#
|
20
|
+
# On a cursory search, this is not documented behavior.
|
21
|
+
#
|
22
|
+
# @param x [Exception|T] The potential Exception to add a backtrace to, if
|
23
|
+
# it is missing a backtrace.
|
24
|
+
# @returns [Exception|T] The passed value, with a backtrace added if it is
|
25
|
+
# an Exception.
|
26
|
+
def self.backtrace_fix(x)
|
27
|
+
if x.kind_of?(Exception) && x.backtrace.nil?
|
28
|
+
raise x
|
29
|
+
else
|
30
|
+
x
|
31
|
+
end
|
32
|
+
rescue => e
|
33
|
+
e
|
34
|
+
end
|
35
|
+
|
9
36
|
##
|
10
37
|
# Create an Err.
|
11
38
|
#
|
@@ -15,29 +42,16 @@ module MonadOxide
|
|
15
42
|
# causes the backtrace to be populated and will be availabl to any cosumers
|
16
43
|
# automatically.
|
17
44
|
#
|
18
|
-
# @param data [
|
19
|
-
#
|
20
|
-
#
|
45
|
+
# @param data [T|Array<T>] The data for this Err. If it is an Exception or
|
46
|
+
# an Array of Exceptions, this will add a backtrace
|
47
|
+
# if it the Exceptions do not have backtraces
|
48
|
+
# already. Exception it will result in a
|
49
|
+
# TypeError.
|
21
50
|
def initialize(data)
|
22
|
-
if
|
23
|
-
|
51
|
+
if data.kind_of?(Array)
|
52
|
+
@data = data.map(&self.class.method(:backtrace_fix))
|
24
53
|
else
|
25
|
-
|
26
|
-
# Ruby Exceptions do not come with a backtrace. During the act of
|
27
|
-
# raising an Exception, that Exception is granted a backtrace. So any
|
28
|
-
# kind of `Exception.new()' invocations will have a `nil' value for
|
29
|
-
# `backtrace()'. To get around this, we can simply raise the Exception
|
30
|
-
# here, and then we get the backtrace we want.
|
31
|
-
#
|
32
|
-
# On a cursory search, this is not documented behavior.
|
33
|
-
if data.backtrace.nil?
|
34
|
-
raise data
|
35
|
-
else
|
36
|
-
@data = data
|
37
|
-
end
|
38
|
-
rescue => e
|
39
|
-
@data = e
|
40
|
-
end
|
54
|
+
@data = self.class.backtrace_fix(data)
|
41
55
|
end
|
42
56
|
end
|
43
57
|
|
@@ -151,5 +165,6 @@ module MonadOxide
|
|
151
165
|
def unwrap_err()
|
152
166
|
@data
|
153
167
|
end
|
168
|
+
|
154
169
|
end
|
155
170
|
end
|
data/lib/monad-oxide.rb
CHANGED
data/lib/result.rb
CHANGED
@@ -99,6 +99,34 @@ module MonadOxide
|
|
99
99
|
Err.new(ResultMethodNotImplementedError.new())
|
100
100
|
end
|
101
101
|
|
102
|
+
##
|
103
|
+
# In the case of `Err', applies `f' or the block over the `Exception' and
|
104
|
+
# returns the same `Err'. No changes are applied. This is ideal for logging.
|
105
|
+
# For `Ok', this method falls through. Exceptions raised during these
|
106
|
+
# transformations will return an `Err' with the Exception.
|
107
|
+
# @param f [Proc<A, B>] The function to call. Could be a block instead.
|
108
|
+
# Takes an [A=Exception] the return is ignored.
|
109
|
+
# @yield Will yield a block that takes an A the return is ignored. Same as
|
110
|
+
# `f' parameter.
|
111
|
+
# @return [Result<A>] returns self.
|
112
|
+
def inspect_err(f=nil, &block)
|
113
|
+
Err.new(ResultMethodNotImplementedError.new())
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# In the case of `Ok', applies `f' or the block over the data and returns
|
118
|
+
# the same `Ok'. No changes are applied. This is ideal for logging. For
|
119
|
+
# `Err', this method falls through. Exceptions raised during these
|
120
|
+
# transformations will return an `Err' with the Exception.
|
121
|
+
# @param f [Proc<A, B>] The function to call. Could be a block instead.
|
122
|
+
# Takes an [A] the return is ignored.
|
123
|
+
# @yield Will yield a block that takes an A the return is ignored. Same as
|
124
|
+
# `f' parameter.
|
125
|
+
# @return [Result<A>] returns self.
|
126
|
+
def inspect_ok(f=nil, &block)
|
127
|
+
Err.new(ResultMethodNotImplementedError.new())
|
128
|
+
end
|
129
|
+
|
102
130
|
##
|
103
131
|
# In the case of `Ok', applies `f' or the block over the data and returns a
|
104
132
|
# new new `Ok' with the returned value. For `Err', this method falls
|
@@ -132,31 +160,23 @@ module MonadOxide
|
|
132
160
|
end
|
133
161
|
|
134
162
|
##
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
#
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
#
|
150
|
-
|
151
|
-
|
152
|
-
# transformations will return an `Err' with the Exception.
|
153
|
-
# @param f [Proc<A, B>] The function to call. Could be a block instead.
|
154
|
-
# Takes an [A] the return is ignored.
|
155
|
-
# @yield Will yield a block that takes an A the return is ignored. Same as
|
156
|
-
# `f' parameter.
|
157
|
-
# @return [Result<A>] returns self.
|
158
|
-
def inspect_ok(f=nil, &block)
|
159
|
-
Err.new(ResultMethodNotImplementedError.new())
|
163
|
+
# Use pattern matching to work with both Ok and Err variants. This is useful
|
164
|
+
# when it is desirable to have both variants handled in the same location.
|
165
|
+
# It can also be useful when either variant can coerced into a non-Result
|
166
|
+
# type.
|
167
|
+
#
|
168
|
+
# Ruby has no built-in pattern matching, but the next best thing is a Hash
|
169
|
+
# using the Result classes themselves as the keys.
|
170
|
+
#
|
171
|
+
# Tests for this are found in Ok and Err's tests.
|
172
|
+
#
|
173
|
+
# @param matcher [Hash<Class, Proc<T | E, R>] matcher The matcher to match
|
174
|
+
# upon.
|
175
|
+
# @option matcher [Proc] MonadOxide::Ok The branch to execute for Ok.
|
176
|
+
# @option matcher [Proc] MonadOxide::Err The branch to execute for Err.
|
177
|
+
# @return [R] The return value of the executed Proc.
|
178
|
+
def match(matcher)
|
179
|
+
matcher[self.class].call(@data)
|
160
180
|
end
|
161
181
|
|
162
182
|
##
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: monad-oxide
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Logan Barnett
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: org-ruby
|
@@ -75,6 +75,7 @@ executables: []
|
|
75
75
|
extensions: []
|
76
76
|
extra_rdoc_files: []
|
77
77
|
files:
|
78
|
+
- lib/array.rb
|
78
79
|
- lib/err.rb
|
79
80
|
- lib/monad-oxide.rb
|
80
81
|
- lib/ok.rb
|
@@ -100,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
101
|
- !ruby/object:Gem::Version
|
101
102
|
version: '0'
|
102
103
|
requirements: []
|
103
|
-
rubygems_version: 3.
|
104
|
+
rubygems_version: 3.3.26
|
104
105
|
signing_key:
|
105
106
|
specification_version: 4
|
106
107
|
summary: Ruby port of Rust's Result and Option.
|