mona-result 0.1.3 → 0.2.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: af436f63f473104b9dd2b4bffb0c379e15032c5eee00fbd7b76491f8d7dc3ba0
4
- data.tar.gz: 0a198685c28efc6a3d72b87daf6563fb5ca6876e1990063b659a311ba5bd91a3
3
+ metadata.gz: 11b851820d5a4a5558b4b9fca9ed4d473a4c7f41f76296e8304de95f319b4eac
4
+ data.tar.gz: e02cccae0cc5ddf02a7a8fd99d1f509be1148c9d41f39f28d545409da7906e05
5
5
  SHA512:
6
- metadata.gz: 545a03866806626c22141209e8e5a5b828f5a686cfa54d40a90a3015b5efa3ea6ba404fdb77b2b0869fec30b2f8e035e551b8d836601710324ef3f3cccab5e6a
7
- data.tar.gz: 6886883d884629a9de5fe769016fbb0b44c5a107e6f49bc1c6688c7fd6efab2800da4d47c252985ca8676d7f9d69ae87fbb80e6faeda001c2385447137d6bbef
6
+ metadata.gz: 4b01676a3ec1acaa3541a3e60eeaacd82cfacdc81889bd7073e0824ee987ec89c01415b28ba1a72413a32d78d687d0ac1f0a5521a0933b4a1edae8fe0af6ce46
7
+ data.tar.gz: 66738db3e3571dd6c53982081acf787f634b5f7964a19a58649b513eeb5c3c169ac89bf25aa7fd9aaf951e25c83f9646314eab0d5b7b474f08efe3fe96adbe91
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## [0.2.0] - 2022-08-23
2
+
3
+ - Adds Mona::Resultable module which implements the Result interface
4
+ - Simplify and improve RBS
5
+ - Steep checks tests in a stricter fashion
6
+ - Improve docs, tests, and rubocop
7
+
1
8
  ## [0.1.3] - 2022-08-09
2
9
 
3
10
  - Fix CHANGELOG rubygems link
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mona-result (0.1.3)
4
+ mona-result (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -21,7 +21,7 @@ GEM
21
21
  listen (3.7.1)
22
22
  rb-fsevent (~> 0.10, >= 0.10.3)
23
23
  rb-inotify (~> 0.9, >= 0.9.10)
24
- minitest (5.16.2)
24
+ minitest (5.16.3)
25
25
  parallel (1.22.1)
26
26
  parser (3.1.2.1)
27
27
  ast (~> 2.4.1)
@@ -33,14 +33,14 @@ GEM
33
33
  rbs (2.6.0)
34
34
  regexp_parser (2.5.0)
35
35
  rexml (3.2.5)
36
- rubocop (1.34.0)
36
+ rubocop (1.35.1)
37
37
  json (~> 2.3)
38
38
  parallel (~> 1.10)
39
39
  parser (>= 3.1.2.1)
40
40
  rainbow (>= 2.2.2, < 4.0)
41
41
  regexp_parser (>= 1.8, < 3.0)
42
42
  rexml (>= 3.2.5, < 4.0)
43
- rubocop-ast (>= 1.20.0, < 2.0)
43
+ rubocop-ast (>= 1.20.1, < 2.0)
44
44
  ruby-progressbar (~> 1.7)
45
45
  unicode-display_width (>= 1.4.0, < 3.0)
46
46
  rubocop-ast (1.21.0)
data/README.md CHANGED
@@ -24,7 +24,10 @@ success = Result.ok(1) # => #<OK 1>
24
24
  success.ok? # => true
25
25
  success.err? # => false
26
26
  success.value # => 1
27
- success.and_tap { puts "it is #{_1}" }.and_then { _1 * 5 }.value_or { :nope }
27
+
28
+ success.and_tap { puts "it is #{_1}" }
29
+ .and_then { _1 * 5 }
30
+ .value_or { :nope }
28
31
  # OUT: it is 1
29
32
  # => 5
30
33
 
@@ -34,7 +37,11 @@ failure.ok? # => false
34
37
  failure.err? # => true
35
38
  failure.failure # => 4
36
39
  failure.reason # => :not_prime
37
- failure.and_tap { puts "it is #{_1}" }.and_then { _1 * 5 }.value_or { :nope } # => :nope
40
+
41
+ failure.and_tap { puts "it is #{_1}" }
42
+ .and_then { _1 * 5 }
43
+ .value_or { :nope }
44
+ # => :nope
38
45
 
39
46
  # Dict with sequence, example using a fictional repository.
40
47
  # #set can take a [Symbol, Symbol] key argument where left is OK key, right is Err key
data/Steepfile CHANGED
@@ -6,18 +6,15 @@ target :lib do
6
6
  signature "sig"
7
7
 
8
8
  check "lib"
9
-
10
- configure_code_diagnostics(D::Ruby.default)
11
9
  end
12
10
 
13
11
  target :test do
14
- signature "sig"
12
+ signature "sig", "test/sig"
15
13
 
16
14
  check "test"
17
15
 
18
16
  library "minitest", "mutex_m"
19
17
 
20
- configure_code_diagnostics(D::Ruby.strict)
21
18
  configure_code_diagnostics do |h|
22
19
  h[D::Ruby::UnsupportedSyntax] = :information
23
20
  end
@@ -68,14 +68,18 @@ module Mona
68
68
  remove_instance_variable :@sequence
69
69
  end
70
70
 
71
+ def perform(*args, **kwargs) = raise(NotImplementedError, "implement `perform'")
72
+
71
73
  private
72
74
 
75
+ def get(key) = @sequence.fetch(key)
76
+
73
77
  def set(key, value) = @sequence.set(key, value)
74
78
 
75
79
  def respond_to_missing?(key, _include_private = false) = @sequence.key?(key)
76
80
 
77
81
  def method_missing(key, *args)
78
- return @sequence.fetch(key) if args.empty? && @sequence.key?(key)
82
+ return get(key) if args.empty? && @sequence.key?(key)
79
83
 
80
84
  raise NoMethodError, "no method `#{key}' for #{self}"
81
85
  end
@@ -5,7 +5,7 @@ module Mona
5
5
  # Represents a dictionary of results, it is successful if all results are successful, and a failure if one
6
6
  # is a failure. A Result::Dict can only contain one failure.
7
7
  class Dict
8
- # factory method that returns {Dict::Success} or {Dict::Failure}
8
+ # factory method that returns {Dict::OK} or {Dict::Err}
9
9
  def self.new(initial = {}, &block)
10
10
  result = Dict::EMPTY
11
11
  initial.each { |k, v| result = result.set(k, v) }
@@ -14,7 +14,7 @@ module Mona
14
14
  end
15
15
 
16
16
  # Dict read interface
17
- module ReadInterface
17
+ module Read
18
18
  def [](key) = to_h[key]
19
19
 
20
20
  def key?(key) = to_h.key?(key)
@@ -24,15 +24,16 @@ module Mona
24
24
 
25
25
  # OK dict result
26
26
  class OK < Result::OK
27
- include ReadInterface
27
+ include Read
28
28
 
29
29
  def set(key, to_result)
30
30
  key, failure_key = key if key.is_a?(Array)
31
31
  failure_key ||= key
32
32
 
33
33
  Result[to_result].either \
34
- ->(value) { OK.new to_h.merge(key => value) },
35
- ->(failure, reason, **m) { Err.new to_h.merge(failure_key => failure), reason, **m, key: failure_key }
34
+ ->(value) { OK.new to_h.merge(key => value) },
35
+ # @type var meta: Hash[Symbol, untyped]
36
+ ->(failure, reason, **meta) { Err.new to_h.merge(failure_key => failure), reason, **meta, key: failure_key }
36
37
  end
37
38
 
38
39
  def sequence(&) = Sequence.new(self).call(&)
@@ -42,7 +43,7 @@ module Mona
42
43
 
43
44
  # Err dict result
44
45
  class Err < Result::Err
45
- include ReadInterface
46
+ include Read
46
47
 
47
48
  def set(_key, _val) = raise(Error, "cannot #set on #{self}")
48
49
 
@@ -4,45 +4,25 @@ module Mona
4
4
  module Result
5
5
  # A Error or failure result, with optional reason, and metadata
6
6
  class Err
7
+ include Resultable
8
+
7
9
  def initialize(failure, reason = nil, **meta)
8
- raise ArgumentError, "meta can't contain :reason key" if meta.key?(:reason)
10
+ raise ArgumentError, "meta can't contain :reason or err: key" if meta.key?(:reason) || meta.key?(:err)
9
11
 
10
- @failure = failure.freeze
11
- @reason = reason
12
- @meta = meta
12
+ @failure = failure
13
+ @reason = reason
14
+ @meta = meta
13
15
  end
14
16
 
17
+ # @dynamic failure, reason, meta
15
18
  attr_reader :failure, :reason, :meta
16
19
 
17
- def ok? = false
18
-
19
- def err? = true
20
-
21
- def value_or(&) = yield
22
-
23
- def ok(&) = nil
24
-
25
- def err(&) = yield @failure, @reason, **@meta
26
-
27
20
  def either(_ok, err) = err.call(@failure, @reason, **@meta)
28
21
 
29
- def and_then(&) = self
30
-
31
- def and_tap(&) = self
32
-
33
- def or_else(&) = Result[yield @failure, @reason, **@meta]
34
-
35
- def deconstruct = [:err, @failure, @reason, @meta]
36
-
37
- def deconstruct_keys(_keys = nil) = { err: @failure, reason: @reason, **@meta }
38
-
39
- def to_result = self
40
-
41
- def to_s
42
- "#<Err #{@failure.inspect} #{{ reason: @reason, **@meta }.map{ "#{_1}: #{_2.inspect}" }.join(", ")}>"
43
- end
22
+ def inspect = "#<Err #{@failure} #{{ reason: @reason, **@meta }.map { "#{_1}: #{_2}" }.join(", ")}>"
44
23
 
45
- alias inspect to_s
24
+ # @dynamic to_s
25
+ alias to_s inspect
46
26
  end
47
27
  end
48
28
  end
@@ -7,6 +7,7 @@ module Mona
7
7
 
8
8
  # raised when Result::Match does not match the result
9
9
  class NoMatchError < Error
10
+ # @dynamic result
10
11
  attr_reader :result
11
12
 
12
13
  def initialize(result)
@@ -5,10 +5,11 @@ module Mona
5
5
  # Use Match.call to respond to result success or failure
6
6
  #
7
7
  # Result::Match.call(result) do |r|
8
- # r.ok { |value| ... }
9
- # r.err(error, **meta) { |failure, reason, **meta| ... }
10
- # r.err(error) { |failure, reason, **meta| ... }
11
- # r.err { |failure, reason, **meta| ... }
8
+ # r.ok { |value| ... }
9
+ # r.err(reason, **meta) { |failure, reason, **meta| ... }
10
+ # r.err(**meta) { |failure, reason, **meta| ... }
11
+ # r.err(reason) { |failure, reason, **meta| ... }
12
+ # r.err { |failure, reason, **meta| ... }
12
13
  # end
13
14
  class Match
14
15
  def self.call(result, &) = new(result).call(&)
@@ -33,6 +34,7 @@ module Mona
33
34
 
34
35
  def err(match_reason = nil, **match_meta)
35
36
  @result.or_else do |failure, reason, **meta|
37
+ # @type var meta: Hash[Symbol, untyped]
36
38
  if match_reason?(match_reason, reason) && match_meta?(match_meta, meta)
37
39
  throw @throw, yield(failure, reason, **meta)
38
40
  end
@@ -4,39 +4,21 @@ module Mona
4
4
  module Result
5
5
  # A Successful (OK) result
6
6
  class OK
7
+ include Resultable
8
+
7
9
  def initialize(value)
8
- @value = value.freeze
10
+ @value = value
9
11
  end
10
12
 
13
+ # @dynamic value
11
14
  attr_reader :value
12
15
 
13
- def value_or(&) = @value
14
-
15
- def ok? = true
16
-
17
- def err? = false
18
-
19
- def ok(&) = yield @value
20
-
21
- def err(&) = nil
22
-
23
16
  def either(ok, _err) = ok.call(@value)
24
17
 
25
- def and_then(&) = Result[yield @value]
26
-
27
- def and_tap(&) = tap { yield @value }
28
-
29
- def or_else(&) = self
30
-
31
- def deconstruct = [:ok, @value]
32
-
33
- def deconstruct_keys(_keys = nil) = { ok: @value }
34
-
35
- def to_result = self
36
-
37
- def to_s = "#<OK #{@value.inspect}>"
18
+ def inspect = "#<OK #{@value}>"
38
19
 
39
- alias inspect to_s
20
+ # @dynamic to_s
21
+ alias to_s inspect
40
22
  end
41
23
  end
42
24
  end
@@ -5,7 +5,7 @@ module Mona
5
5
  # Sequence.call { ... } allows monadic 'do' notation for Result::Dict, where #set-ing the first failure skips the
6
6
  # remainder of the block and returns the Result::Dict
7
7
  class Sequence
8
- include Dict::ReadInterface
8
+ include Dict::Read
9
9
 
10
10
  def self.call(result = Dict::EMPTY, &) = new(result).call(&)
11
11
 
data/lib/mona/result.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "result/version"
4
3
  require_relative "result/error"
4
+ require_relative "resultable"
5
5
 
6
6
  module Mona
7
7
  # Monadic result
@@ -9,6 +9,8 @@ module Mona
9
9
  # @author Ian White
10
10
  # @since 0.1.0
11
11
  module Result
12
+ VERSION = "0.2.0"
13
+
12
14
  autoload :OK, "mona/result/ok.rb"
13
15
  autoload :Err, "mona/result/err.rb"
14
16
  autoload :Match, "mona/result/match.rb"
@@ -16,10 +18,12 @@ module Mona
16
18
  autoload :Sequence, "mona/result/sequence.rb"
17
19
  autoload :Action, "mona/result/action.rb"
18
20
 
19
- def self.[](obj) = obj.respond_to?(:to_result) ? obj.to_result : OK.new(obj)
21
+ def self.[](obj) = obj.is_a?(Resultable) ? obj : OK.new(obj)
20
22
 
21
23
  module_function
22
24
 
25
+ # @dynamic self.to_result, self.ok, self.err, self.on_result, self.on_ok, self.dict, self.action
26
+
23
27
  def to_result(obj) = Result[obj]
24
28
 
25
29
  def ok(value) = OK.new(value)
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mona
4
+ # Provides the result interface
5
+ # The including class must implement #either(ok, err)
6
+ module Resultable
7
+ def value_or(&block)
8
+ either ->(value) { value },
9
+ ->(_failure, _reason = nil, **_meta) { block.call }
10
+ end
11
+
12
+ def ok?
13
+ either ->(_value) { true },
14
+ ->(_failure, _reason = nil, **_meta) { false }
15
+ end
16
+
17
+ def err?
18
+ either ->(_value) { false },
19
+ ->(_failure, _reason = nil, **_meta) { true }
20
+ end
21
+
22
+ def ok(&block)
23
+ either ->(value) { block.call(value) },
24
+ ->(_failure, _reason = nil, **_meta) {}
25
+ end
26
+
27
+ def err(&block)
28
+ either ->(_value) {},
29
+ # @type var meta: Hash[Symbol, untyped]
30
+ ->(failure, reason = nil, **meta) { block.call(failure, reason, **meta) }
31
+ end
32
+
33
+ def and_tap(&block)
34
+ tap do
35
+ either ->(value) { block.call(value) },
36
+ ->(_failure, _reason = nil, **_meta) {}
37
+ end
38
+ end
39
+
40
+ def and_then(&block)
41
+ either ->(value) { Result[block.call(value)] },
42
+ ->(_failure, _reason, **_meta) { self }
43
+ end
44
+
45
+ def or_else(&block)
46
+ either ->(_value) { self },
47
+ # @type var meta: Hash[Symbol, untyped]
48
+ ->(failure, reason, **meta) { Result[block.call(failure, reason, **meta)] }
49
+ end
50
+
51
+ def deconstruct
52
+ either ->(value) { [:ok, value] },
53
+ # @type var meta: Hash[Symbol, untyped]
54
+ ->(failure, reason, **meta) { [:err, failure, reason, meta] }
55
+ end
56
+
57
+ def deconstruct_keys(_keys = nil)
58
+ either ->(value) { { ok: value } },
59
+ # @type var meta: Hash[Symbol, untyped]
60
+ ->(failure, reason, **meta) { { err: failure, reason:, **meta } }
61
+ end
62
+ end
63
+ end
data/sig/mona.rbs ADDED
@@ -0,0 +1,157 @@
1
+ module Mona
2
+ type dict = Hash[Symbol, untyped]
3
+ type result[T] = Resultable[T]
4
+ type dict_result = (Result::Dict::OK | Result::Dict::Err)
5
+
6
+ module Resultable[T] : _Either[T]
7
+ interface _Either[T]
8
+ def either: [OKR, ErrR] (^(T) -> OKR, ^(T, ?untyped, **untyped) -> ErrR) -> (OKR | ErrR)
9
+ end
10
+
11
+ def ok?: -> bool
12
+ def err?: -> bool
13
+ def ok: [R] () { (T) -> R } -> (R | nil)
14
+ def err: [R] () { (T, ?untyped, **untyped) -> R } -> (R | nil)
15
+ def value_or: [R] { () -> R } -> (R | T)
16
+ def and_then: [R] () { (T) -> R } -> result[untyped]
17
+ def and_tap: () { (T) -> void } -> self
18
+ def or_else: [R] () { (T, ?untyped, **untyped) -> R } -> result[untyped]
19
+ def deconstruct: -> Array[untyped]
20
+ def deconstruct_keys: (?Array[Symbol]?) -> dict
21
+ end
22
+
23
+ module Result
24
+ VERSION: String
25
+
26
+ def self.[]: (untyped) -> result[untyped]
27
+ def self?.to_result: (untyped) -> result[untyped]
28
+ def self?.ok: [ValueT] (ValueT) -> OK[ValueT]
29
+ def self?.err: [FailureT] (FailureT, ?untyped, **untyped) -> Err[FailureT]
30
+ def self?.dict: (?dict) ?{ (Sequence) -> void } -> dict_result
31
+ def self?.on_result: (result[untyped]) { (Match) -> void } -> untyped
32
+ def self?.on_ok: (result[untyped]) { (untyped) -> void } -> untyped
33
+ def self?.action: () { (*untyped) -> void } -> Action::Ephemeral
34
+
35
+ class Error < StandardError
36
+ end
37
+
38
+ class NoMatchError < Error
39
+ attr_reader result: result[untyped]
40
+ def initialize: (result[untyped]) -> void
41
+ end
42
+
43
+ class OK[ValueT]
44
+ include Resultable[ValueT]
45
+
46
+ attr_reader value: ValueT
47
+
48
+ def initialize: (ValueT) -> void
49
+ def either: [OKR, ErrR] (^(ValueT) -> OKR, ^(untyped, ?untyped, **untyped) -> ErrR) -> OKR
50
+ def inspect: -> String
51
+ alias to_s inspect
52
+ end
53
+
54
+ class Err[FailureT]
55
+ include Resultable[FailureT]
56
+
57
+ attr_reader failure: FailureT
58
+ attr_reader reason: untyped
59
+ attr_reader meta: dict
60
+
61
+ def initialize: (FailureT, ?untyped, **untyped) -> void
62
+ def either: [OKR, ErrR] (^(untyped) -> OKR, ^(FailureT, ?untyped, **untyped) -> ErrR) -> ErrR
63
+ def inspect: -> String
64
+ alias to_s inspect
65
+ end
66
+
67
+ class Dict
68
+ EMPTY: dict_result
69
+
70
+ module Read : _ToH
71
+ interface _ToH
72
+ def to_h: -> dict
73
+ end
74
+
75
+ def key? : (Symbol) -> bool
76
+ def fetch : (Symbol) -> untyped
77
+ def [] : (Symbol) -> untyped
78
+ end
79
+
80
+ interface _Interface
81
+ def set: (Symbol | [Symbol, Symbol], untyped) -> dict_result
82
+ def sequence: () { (Sequence) -> void } -> dict_result
83
+ def to_h: -> dict
84
+ end
85
+
86
+ class OK < Result::OK[dict]
87
+ include Read
88
+
89
+ include _Interface
90
+
91
+ @value: dict
92
+ end
93
+
94
+ class Err < Result::Err[dict]
95
+ include Read
96
+
97
+ include _Interface
98
+
99
+ @failure: dict
100
+ end
101
+
102
+ def self.new: (?dict) ?{ (Sequence) -> void } -> dict_result
103
+ end
104
+
105
+ class Match
106
+ @throw: Object
107
+ @result: result[untyped]
108
+
109
+ def self.call: (result[untyped]) { (Match) -> void } -> untyped
110
+ def initialize: (result[untyped]) -> void
111
+ def call: () { (Match) -> void } -> untyped
112
+ def ok: () { (untyped) -> void } -> void
113
+ def err: (?untyped, **untyped) { (untyped, ?untyped, **untyped) -> void } -> void
114
+
115
+ private
116
+
117
+ def match_reason?: (untyped, untyped) -> bool
118
+ def match_meta?: (untyped, untyped) -> bool
119
+ end
120
+
121
+ class Sequence
122
+ include Dict::Read
123
+
124
+ @throw: Object
125
+ @result: dict_result
126
+
127
+ def self.call: (?dict_result) { (Sequence) -> void } -> dict_result
128
+ def initialize: (?dict_result) -> void
129
+ def call: () { (Sequence) -> void } -> dict_result
130
+ def set: (Symbol | [Symbol,Symbol], untyped) -> void
131
+ def to_h: -> dict
132
+ end
133
+
134
+ module Action
135
+ class Ephemeral
136
+ include Action
137
+
138
+ @perform: ^(*untyped, **untyped) -> void
139
+
140
+ def initialize: () { (*untyped, **untyped) -> void } -> void
141
+ def perform: (*untyped, **untyped) -> void
142
+ end
143
+
144
+ @sequence: Sequence
145
+
146
+ def call: (*untyped, **untyped) -> dict_result
147
+ def perform: (*untyped, **untyped) -> void
148
+
149
+ private
150
+
151
+ def get: (Symbol) -> untyped
152
+ def set: (Symbol | [Symbol,Symbol], untyped) -> void
153
+ def respond_to_missing?: (Symbol, ?bool) -> bool
154
+ def method_missing: (Symbol, *untyped) -> untyped
155
+ end
156
+ end
157
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mona-result
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian White
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-09 00:00:00.000000000 Z
11
+ date: 2022-08-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Mona::Result provides a result monad, and dict result monad with do-notation
14
14
  email:
@@ -33,8 +33,8 @@ files:
33
33
  - lib/mona/result/match.rb
34
34
  - lib/mona/result/ok.rb
35
35
  - lib/mona/result/sequence.rb
36
- - lib/mona/result/version.rb
37
- - sig/mona/result.rbs
36
+ - lib/mona/resultable.rb
37
+ - sig/mona.rbs
38
38
  homepage: https://github.com/mona-rb/mona-result
39
39
  licenses:
40
40
  - MIT
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mona
4
- module Result
5
- VERSION = "0.1.3"
6
- end
7
- end
data/sig/mona/result.rbs DELETED
@@ -1,177 +0,0 @@
1
- module Mona
2
- module Result
3
- VERSION: String
4
-
5
- type dict = Hash[Symbol, untyped]
6
- type keys = Array[Symbol]
7
- type result[T] = (_OK[T] | _Err[T])
8
- type dict_result = result[dict] & _Dict
9
- type set_key = (Symbol | [Symbol, Symbol])
10
-
11
- def self.[]: (untyped) -> result[untyped]
12
- def self?.to_result: (untyped) -> result[untyped]
13
- def self?.ok: [T] (T) -> _OK[T]
14
- def self?.err: [T] (T, ?untyped, **untyped) -> _Err[T]
15
- def self?.dict: (?dict) ?{ (Sequence) -> void } -> dict_result
16
- def self?.on_result: (result[untyped]) { (Match) -> void } -> untyped
17
- def self?.on_ok: (result[untyped]) { (untyped) -> void } -> untyped
18
- def self?.action: () { (*untyped) -> void } -> Action::Ephemeral
19
-
20
- interface _OK[T]
21
- def initialize: (T) -> void
22
- def value: -> T
23
- def ok?: -> true
24
- def err?: -> false
25
- def ok: [R] () { (T) -> R } -> R
26
- def err: () { (T, untyped, **untyped) -> void } -> nil
27
- def either: [R] (^(T) -> R, ^(T, untyped, **untyped) -> void) -> R
28
- def value_or: () { -> void } -> T
29
- def and_then: () { (T) -> untyped } -> result[untyped]
30
- def and_tap: () { (T) -> void } -> self
31
- def or_else: () { (T, ?untyped, **untyped) -> untyped } -> self
32
- def deconstruct: -> [:ok, T]
33
- def deconstruct_keys: (?keys?) -> { ok: T }
34
- end
35
-
36
- interface _Err[T]
37
- def initialize: (T, ?untyped, **untyped) -> void
38
- def failure: -> T
39
- def reason: -> untyped
40
- def meta: -> dict
41
- def ok?: -> false
42
- def err?: -> true
43
- def ok: () { (untyped) -> void } -> nil
44
- def err: [R] () { (T, untyped, **untyped) -> R } -> R
45
- def either: [R] (^(T) -> void, ^(T, untyped, **untyped) -> R) -> R
46
- def value_or: [R] () { -> R } -> R
47
- def and_then: () { (T) -> untyped } -> self
48
- def and_tap: () { (T) -> void } -> self
49
- def or_else: () { (T, ?untyped, **untyped) -> untyped } -> result[untyped]
50
- def deconstruct: -> [:err, T, untyped, dict]
51
- def deconstruct_keys: (?keys?) -> dict
52
- end
53
-
54
- interface _ToH
55
- def to_h: -> dict
56
- end
57
-
58
- interface _DictRead
59
- def key? : (Symbol) -> bool
60
- def fetch : (Symbol) -> untyped
61
- def [] : (Symbol) -> untyped
62
- end
63
-
64
- interface _Dict
65
- include _DictRead
66
- def set: (set_key, untyped) -> dict_result
67
- def sequence: () { (Sequence) -> void } -> dict_result
68
- def to_h: -> dict
69
- end
70
-
71
- interface _Perform
72
- def perform: (*untyped, **untyped) -> void
73
- end
74
-
75
- class Error < StandardError
76
- end
77
-
78
- class NoMatchError < Error
79
- attr_reader result: _Err[untyped]
80
- def initialize: (_Err[untyped]) -> void
81
- end
82
-
83
- class OK
84
- include _OK[untyped]
85
-
86
- @value: untyped
87
- end
88
-
89
- class Err
90
- include _Err[untyped]
91
-
92
- @failure: untyped
93
- @reason: untyped
94
- @meta: dict
95
- end
96
-
97
- class Dict
98
- EMPTY: dict_result
99
-
100
- module ReadInterface : _ToH
101
- include _DictRead
102
- end
103
-
104
- class OK < Result::OK
105
- include ReadInterface
106
-
107
- include _OK[dict]
108
- include _Dict
109
-
110
- @value: dict
111
- end
112
-
113
- class Err < Result::Err
114
- include ReadInterface
115
-
116
- include _Err[dict]
117
- include _Dict
118
-
119
- @failure: dict
120
- @reason: untyped
121
- @meta: dict
122
- end
123
-
124
- def self.new: (?dict) ?{ (Sequence) -> void } -> dict_result
125
- end
126
-
127
- class Match
128
- @throw: Object
129
- @result: result[untyped]
130
-
131
- def self.call: (result[untyped]) { (Match) -> void } -> untyped
132
- def initialize: (result[untyped]) -> void
133
- def call: () { (Match) -> void } -> untyped
134
- def ok: () { (untyped) -> void } -> void
135
- def err: (?untyped, **untyped) { (untyped, ?untyped, **untyped) -> void } -> void
136
-
137
- private
138
-
139
- def match_reason?: (untyped, untyped) -> bool
140
- def match_meta?: (untyped, untyped) -> bool
141
- end
142
-
143
- class Sequence
144
- include Dict::ReadInterface
145
-
146
- @throw: Object
147
- @result: dict_result
148
-
149
- def self.call: (?dict_result) { (Sequence) -> void } -> dict_result
150
- def initialize: (?dict_result) -> void
151
- def call: () { (Sequence) -> void } -> dict_result
152
- def set: (set_key, untyped) -> void
153
- def to_h: -> dict
154
- end
155
-
156
- module Action : _Perform
157
- class Ephemeral
158
- include Action
159
-
160
- @perform: ^(*untyped, **untyped) -> void
161
-
162
- def initialize: () { (*untyped, **untyped) -> void } -> void
163
- def perform: (*untyped, **untyped) -> void
164
- end
165
-
166
- @sequence: Sequence
167
-
168
- def call: (*untyped, **untyped) -> dict_result
169
-
170
- private
171
-
172
- def set: (set_key, untyped) -> void
173
- def respond_to_missing?: (Symbol, ?bool) -> bool
174
- def method_missing: (Symbol, *untyped) -> untyped
175
- end
176
- end
177
- end