monad-oxide 0.3.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9e34a9c5d348e0d022e91919a9d4f8c3c3337cc4040e3c6003a21395db4a553
4
- data.tar.gz: 589f27d397f02deddc8e4372fc1ddbf553803e301ed5cff6df176d7e0d740c79
3
+ metadata.gz: eb1f3b4527006d3ab2dac1f0bd4f4a34ba51b5322be9f399b8aac2c329a0522f
4
+ data.tar.gz: cea1e0e146c40f451d1cfacf37b8c00b588bbd54b45426a1ba2d6b66e7a51017
5
5
  SHA512:
6
- metadata.gz: 30d113b3edff4cc76192203e038606d62cdb306fc4baf386b40ef60b6bef1eb6638d5b26c2a2f0496ca990c96a12ae902b8d92c55babcff74de385c24bf99c39
7
- data.tar.gz: 58f34dc9b1d67dceb2c229f8f53fce8cf6f309a8625bbe267166840482f77001c511306cada76212b5f7022d6ed1fcffbf05d2d675ae51be186ff26bed16bce9
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 [Exception] This must be an Exception it will result in a
19
- # TypeError.
20
- # @raise [TypeError] Is raised if the input is not an Exception.
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 !data.kind_of?(Exception)
23
- raise TypeError.new("#{data.inspect} is not an Exception.")
51
+ if data.kind_of?(Array)
52
+ @data = data.map(&self.class.method(:backtrace_fix))
24
53
  else
25
- begin
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
@@ -1,6 +1,7 @@
1
1
  require_relative './result'
2
2
  require_relative './err'
3
3
  require_relative './ok'
4
+ require_relative './array'
4
5
  require_relative './version'
5
6
 
6
7
  ##
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
- # In the case of `Err', applies `f' or the block over the `Exception' and
136
- # returns the same `Err'. No changes are applied. This is ideal for logging.
137
- # For `Ok', this method falls through. Exceptions raised during these
138
- # transformations will return an `Err' with the Exception.
139
- # @param f [Proc<A, B>] The function to call. Could be a block instead.
140
- # Takes an [A=Exception] the return is ignored.
141
- # @yield Will yield a block that takes an A the return is ignored. Same as
142
- # `f' parameter.
143
- # @return [Result<A>] returns self.
144
- def inspect_err(f=nil, &block)
145
- Err.new(ResultMethodNotImplementedError.new())
146
- end
147
-
148
- ##
149
- # In the case of `Ok', applies `f' or the block over the data and returns
150
- # the same `Ok'. No changes are applied. This is ideal for logging. For
151
- # `Err', this method falls through. Exceptions raised during these
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
@@ -3,5 +3,5 @@ module MonadOxide
3
3
  # This version is locked to 0.x.0 because semver is a lie and this project
4
4
  # uses CICD to push new versions. Any commits that appear on main will result
5
5
  # in a new version of the gem created and published.
6
- VERSION='0.3.0'
6
+ VERSION='0.5.0'
7
7
  end
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.3.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: 2022-07-25 00:00:00.000000000 Z
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.1.6
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.