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