muina 0.5.0 → 0.7.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/CHANGELOG.md +75 -0
- data/README.md +44 -0
- data/lib/muina/maybe/none.rb +78 -13
- data/lib/muina/maybe/some.rb +78 -11
- data/lib/muina/maybe.rb +194 -4
- data/lib/muina/result/failure.rb +1 -1
- data/lib/muina/result/success.rb +1 -1
- data/lib/muina/result.rb +3 -0
- data/lib/muina/version.rb +3 -1
- data/lib/muina.rb +6 -4
- metadata +54 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87250c8fd172242920c2202f5a0bf6de8810d04872c21eb686b40a56262166d2
|
4
|
+
data.tar.gz: 91768a6bb9ed9d3421d330825ff304a57bbb76c3d4b544ab0483cfd69bc5979f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0dbbc867a38c6c935678c4bd20f5c3d1412070ac57d6e555edcc48c9b0b36a3a83c94ac488f7ce6d01363585d0ac2154dbc3a81c94a9ba02419a44edcab49d5a
|
7
|
+
data.tar.gz: a20866b554d759d6be67c7926609138867833b7515dfbba39ed145fe76bf867bf7b3554559d8ccd40b9b36998b68fef180ee0671fc6b03bdff7d96a28617766f
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
### Added
|
10
|
+
* `sorbet-runtime` dependency.
|
11
|
+
* Proper documentation in code for `Muina::Maybe` and its subclasses.
|
12
|
+
* Strictly typed `Muina::Maybe` and its subclasses.
|
13
|
+
* Following sections to the `README`:
|
14
|
+
* Installation
|
15
|
+
* Documentation
|
16
|
+
* Changelog
|
17
|
+
* Development Standards
|
18
|
+
* Supported Ruby Versions
|
19
|
+
* Contributing
|
20
|
+
* License
|
21
|
+
|
22
|
+
|
23
|
+
### Removed
|
24
|
+
* `muina` no longer uses `zeitwerk`.
|
25
|
+
|
26
|
+
|
27
|
+
## [0.6.0] - 2024-06-08
|
28
|
+
### Added
|
29
|
+
* `Muina::Maybe#some` alias for `Muina::Maybe#return`.
|
30
|
+
* `Muina::Error` as main error class.
|
31
|
+
* `Muina::Maybe::UnwrappingError` for `Muina::Maybe::None#value!`.
|
32
|
+
|
33
|
+
|
34
|
+
## [0.5.0] - 2024-06-03
|
35
|
+
### Added
|
36
|
+
* `Muina::Maybe::Some#==`
|
37
|
+
* `Muina::Maybe::None#==`
|
38
|
+
|
39
|
+
|
40
|
+
## [0.4.0] - 2024-06-02
|
41
|
+
### Added
|
42
|
+
* `Muina::Result`
|
43
|
+
|
44
|
+
|
45
|
+
## [0.3.0] - 2024-06-02
|
46
|
+
### Added
|
47
|
+
* `Muina::Maybe`
|
48
|
+
|
49
|
+
|
50
|
+
## [0.2.1] to [0.2.8] - 2021
|
51
|
+
Changelog entries missing.
|
52
|
+
|
53
|
+
|
54
|
+
## [0.2.0] - 2021-06-28
|
55
|
+
### Added
|
56
|
+
* Muina::Action: step based result returning services
|
57
|
+
* Muina::Result#{value!,error!,and_then,or_else}: safe and unsafe ways of unwrapping values and errors
|
58
|
+
|
59
|
+
### Removed
|
60
|
+
* Muina::Result#{value,error}
|
61
|
+
|
62
|
+
|
63
|
+
## [0.1.1] - 2021-06-22
|
64
|
+
### Fixed
|
65
|
+
* Add missing `zeitwerk` dependency to gemspec
|
66
|
+
|
67
|
+
|
68
|
+
## [0.1.0] - 2021-06-21
|
69
|
+
### Added
|
70
|
+
* Muina::Params: self extracting typed params
|
71
|
+
* Muina::PrivateCreation: mixin to make `.new` and `.allocate` private
|
72
|
+
* Muina::Result: type safe result monad
|
73
|
+
* Muina::Service: service object with typesafe constants and attributes
|
74
|
+
* Muina::Value: typesafe immutable struct-like objects
|
75
|
+
* `muina` CLI: to copy bundled rbi file
|
data/README.md
CHANGED
@@ -1 +1,45 @@
|
|
1
1
|
# Muina
|
2
|
+
[][docs]
|
3
|
+
|
4
|
+
`muina` is a gem that provides the `Maybe` monad.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
```
|
8
|
+
bundle add muina
|
9
|
+
```
|
10
|
+
|
11
|
+
|
12
|
+
## Documentation
|
13
|
+
[https://rubydoc.info/gems/muina][docs]
|
14
|
+
|
15
|
+
|
16
|
+
## Changelog
|
17
|
+
See [`CHANGELOG.md`](./CHANGELOG.md)
|
18
|
+
|
19
|
+
|
20
|
+
## Development Standards
|
21
|
+
This project uses several tools to enforce quality standards:
|
22
|
+
* This project has no `rubocop` offenses and uses the style defined by
|
23
|
+
`rubocop-vaporyhumo`.
|
24
|
+
* This project has `100%` test coverage.
|
25
|
+
* This project has `100%` mutation test coverage.
|
26
|
+
* This project has no significant code duplication.
|
27
|
+
* This project is strictly typed using `sorbet`.
|
28
|
+
|
29
|
+
|
30
|
+
## Supported Ruby Versions
|
31
|
+
This gem supports Ruby `3.1` and newer versions.
|
32
|
+
|
33
|
+
|
34
|
+
## Contributing
|
35
|
+
If you find any issues with the documentation or encounter any unexpected errors
|
36
|
+
please open a GitHub Issue in the repository.
|
37
|
+
|
38
|
+
This project does not accept code contributions.
|
39
|
+
|
40
|
+
|
41
|
+
## License
|
42
|
+
See [`LICENSE`](./LICENSE)
|
43
|
+
|
44
|
+
|
45
|
+
[docs]: https://rubygems.org/gems/muina
|
data/lib/muina/maybe/none.rb
CHANGED
@@ -1,65 +1,130 @@
|
|
1
|
+
# typed: strict
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Muina
|
4
5
|
class Maybe
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
7
|
+
|
5
8
|
class None < self
|
9
|
+
class << self
|
10
|
+
undef_method :some
|
11
|
+
undef_method :none
|
12
|
+
end
|
13
|
+
|
14
|
+
Elem = type_member
|
15
|
+
ElemT = type_template { { upper: Object } }
|
16
|
+
|
6
17
|
private_class_method(:new)
|
7
|
-
|
18
|
+
sig { void }
|
19
|
+
def initialize # rubocop:disable Lint/MissingSuper
|
8
20
|
freeze
|
9
21
|
end
|
10
22
|
|
23
|
+
sig { override.returns T::Boolean }
|
24
|
+
# (see Maybe#some?)
|
11
25
|
def some?
|
12
26
|
false
|
13
27
|
end
|
14
28
|
|
29
|
+
sig { override.returns T::Boolean }
|
30
|
+
# (see Maybe#none?)
|
15
31
|
def none?
|
16
32
|
true
|
17
33
|
end
|
18
34
|
|
35
|
+
sig { override.returns Elem }
|
36
|
+
# (see Maybe#value!)
|
19
37
|
def value!
|
20
|
-
raise
|
38
|
+
raise UnwrappingError
|
21
39
|
end
|
22
40
|
|
41
|
+
sig do
|
42
|
+
override.type_parameters(:Default)
|
43
|
+
.params(default: T.type_parameter(:Default))
|
44
|
+
.returns(T.any(Elem, T.type_parameter(:Default)))
|
45
|
+
end
|
46
|
+
# (see Maybe#value_or)
|
23
47
|
def value_or(default)
|
24
48
|
default
|
25
49
|
end
|
26
50
|
|
27
|
-
|
51
|
+
sig do
|
52
|
+
override.type_parameters(:T)
|
53
|
+
.params(_blk: T.proc.returns(T.type_parameter(:T)))
|
54
|
+
.returns(T.any(Elem, T.type_parameter(:T)))
|
55
|
+
end
|
56
|
+
# (see Maybe#value_or_yield)
|
57
|
+
def value_or_yield(&_blk)
|
28
58
|
yield
|
29
59
|
end
|
30
60
|
|
31
|
-
|
32
|
-
|
33
|
-
end
|
61
|
+
sig { override.returns(T.any(Elem, NilClass)) }
|
62
|
+
# (see Maybe#value_or_nil)
|
63
|
+
def value_or_nil; end
|
34
64
|
|
35
|
-
|
65
|
+
sig { override.params(_blk: T.untyped).returns(T.self_type) }
|
66
|
+
# (see Maybe#and_then)
|
67
|
+
def and_then(&_blk)
|
36
68
|
self
|
37
69
|
end
|
38
70
|
|
39
|
-
|
71
|
+
sig { override.params(_blk: T.untyped).returns(T.self_type) }
|
72
|
+
# (see Maybe#or_else)
|
73
|
+
def or_else(&_blk)
|
40
74
|
yield
|
41
75
|
self
|
42
76
|
end
|
43
77
|
|
44
|
-
|
78
|
+
sig do
|
79
|
+
override.type_parameters(:T)
|
80
|
+
.params(
|
81
|
+
_blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:T))
|
82
|
+
)
|
83
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
84
|
+
end
|
85
|
+
# (see Maybe#map)
|
86
|
+
def map(&_blk)
|
45
87
|
self
|
46
88
|
end
|
47
89
|
|
48
|
-
|
90
|
+
sig do
|
91
|
+
override.type_parameters(:T)
|
92
|
+
.params(_blk: T.proc.returns(T.type_parameter(:T)))
|
93
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
94
|
+
end
|
95
|
+
# (see Maybe#map_none)
|
96
|
+
def map_none(&_blk)
|
49
97
|
Maybe.return yield
|
50
98
|
end
|
51
99
|
|
52
|
-
|
100
|
+
sig do
|
101
|
+
override.type_parameters(:T)
|
102
|
+
.params(
|
103
|
+
_blk: T.proc.params(arg0: Elem).returns(Maybe[T.type_parameter(:T)])
|
104
|
+
)
|
105
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
106
|
+
end
|
107
|
+
# (see Maybe#bind)
|
108
|
+
def bind(&_blk)
|
53
109
|
self
|
54
110
|
end
|
55
111
|
|
56
|
-
|
112
|
+
sig do
|
113
|
+
override.type_parameters(:T)
|
114
|
+
.params(_blk: T.proc.returns(Maybe[T.type_parameter(:T)]))
|
115
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
116
|
+
end
|
117
|
+
# (see Maybe#bind_none)
|
118
|
+
def bind_none(&_blk)
|
57
119
|
yield
|
58
120
|
end
|
59
121
|
|
122
|
+
sig { override.params(other: T.untyped).returns(T::Boolean) }
|
123
|
+
# (see Maybe#==)
|
60
124
|
def ==(other)
|
61
|
-
self.class
|
125
|
+
other.instance_of?(self.class)
|
62
126
|
end
|
63
127
|
end
|
128
|
+
# rubocop:enable Metrics/ClassLength
|
64
129
|
end
|
65
130
|
end
|
data/lib/muina/maybe/some.rb
CHANGED
@@ -1,67 +1,134 @@
|
|
1
|
+
# typed: strict
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Muina
|
4
5
|
class Maybe
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
7
|
+
|
5
8
|
class Some < self
|
6
|
-
|
9
|
+
class << self
|
10
|
+
undef_method :some
|
11
|
+
undef_method :none
|
12
|
+
end
|
13
|
+
|
14
|
+
Elem = type_member { { upper: Object } }
|
15
|
+
ElemT = type_template { { upper: Object } }
|
16
|
+
|
17
|
+
private_class_method(:new)
|
18
|
+
sig { params(value: Elem).void }
|
19
|
+
def initialize(value) # rubocop:disable Lint/MissingSuper
|
7
20
|
@value = value
|
8
21
|
freeze
|
9
22
|
end
|
10
|
-
private_class_method(:new)
|
11
23
|
|
24
|
+
# (see Maybe#some?)
|
25
|
+
sig { override.returns T::Boolean }
|
12
26
|
def some?
|
13
27
|
true
|
14
28
|
end
|
15
29
|
|
30
|
+
sig { override.returns T::Boolean }
|
31
|
+
# (see Maybe#none?)
|
16
32
|
def none?
|
17
33
|
false
|
18
34
|
end
|
19
35
|
|
36
|
+
sig { override.returns Elem }
|
37
|
+
# (see Maybe#value!)
|
20
38
|
def value!
|
21
39
|
@value
|
22
40
|
end
|
23
41
|
|
24
|
-
|
42
|
+
# (see Maybe#value_or)
|
43
|
+
sig do
|
44
|
+
override.type_parameters(:Default)
|
45
|
+
.params(_default: T.type_parameter(:Default))
|
46
|
+
.returns(T.any(Elem, T.type_parameter(:Default)))
|
47
|
+
end
|
48
|
+
def value_or(_default)
|
25
49
|
@value
|
26
50
|
end
|
27
51
|
|
28
|
-
|
52
|
+
sig do
|
53
|
+
override.type_parameters(:T)
|
54
|
+
.params(_blk: T.proc.returns(T.type_parameter(:T)))
|
55
|
+
.returns(T.any(Elem, T.type_parameter(:T)))
|
56
|
+
end
|
57
|
+
# (see Maybe#value_or_yield)
|
58
|
+
def value_or_yield(&_blk)
|
29
59
|
@value
|
30
60
|
end
|
31
61
|
|
62
|
+
sig { override.returns(T.any(Elem, NilClass)) }
|
63
|
+
# (see Maybe#value_or_nil)
|
32
64
|
def value_or_nil
|
33
65
|
@value
|
34
66
|
end
|
35
67
|
|
36
|
-
|
68
|
+
sig { override.params(_blk: T.untyped).returns(T.self_type) }
|
69
|
+
# (see Maybe#and_then)
|
70
|
+
def and_then(&_blk)
|
37
71
|
yield(@value)
|
38
72
|
self
|
39
73
|
end
|
40
74
|
|
41
|
-
|
75
|
+
sig { override.params(_blk: T.untyped).returns(T.self_type) }
|
76
|
+
# (see Maybe#or_else)
|
77
|
+
def or_else(&_blk)
|
42
78
|
self
|
43
79
|
end
|
44
80
|
|
45
|
-
|
81
|
+
sig do
|
82
|
+
override.type_parameters(:T)
|
83
|
+
.params(
|
84
|
+
_blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:T))
|
85
|
+
)
|
86
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
87
|
+
end
|
88
|
+
# (see Maybe#map)
|
89
|
+
def map(&_blk)
|
46
90
|
Maybe.return yield(@value)
|
47
91
|
end
|
48
92
|
|
49
|
-
|
93
|
+
sig do
|
94
|
+
override.type_parameters(:T)
|
95
|
+
.params(_blk: T.proc.returns(T.type_parameter(:T)))
|
96
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
97
|
+
end
|
98
|
+
# (see Maybe#map_none)
|
99
|
+
def map_none(&_blk)
|
50
100
|
self
|
51
101
|
end
|
52
102
|
|
53
|
-
|
103
|
+
sig do
|
104
|
+
override.type_parameters(:T)
|
105
|
+
.params(
|
106
|
+
_blk: T.proc.params(arg0: Elem).returns(Maybe[T.type_parameter(:T)])
|
107
|
+
)
|
108
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
109
|
+
end
|
110
|
+
# (see Maybe#bind)
|
111
|
+
def bind(&_blk)
|
54
112
|
yield(@value)
|
55
113
|
end
|
56
114
|
|
57
|
-
|
115
|
+
sig do
|
116
|
+
override.type_parameters(:T)
|
117
|
+
.params(_blk: T.proc.returns(Maybe[T.type_parameter(:T)]))
|
118
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
119
|
+
end
|
120
|
+
# (see Maybe#bind_none)
|
121
|
+
def bind_none(&_blk)
|
58
122
|
self
|
59
123
|
end
|
60
124
|
|
125
|
+
sig { override.params(other: T.untyped).returns(T::Boolean) }
|
126
|
+
# (see Maybe#==)
|
61
127
|
def ==(other)
|
62
128
|
self.class == other.class &&
|
63
|
-
|
129
|
+
value! == other.value!
|
64
130
|
end
|
65
131
|
end
|
132
|
+
# rubocop:enable Metrics/ClassLength
|
66
133
|
end
|
67
134
|
end
|
data/lib/muina/maybe.rb
CHANGED
@@ -1,13 +1,203 @@
|
|
1
|
+
# typed: strict
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Muina
|
5
|
+
# rubocop:disable Metrics/ClassLength
|
6
|
+
|
7
|
+
# @abstract
|
8
|
+
# @param [Elem] elem the type of element maybe contained inside the monad
|
4
9
|
class Maybe
|
5
|
-
|
6
|
-
|
10
|
+
extend T::Sig
|
11
|
+
extend T::Helpers
|
12
|
+
extend T::Generic
|
13
|
+
|
14
|
+
# Raised when trying to unwrap a {None} value
|
15
|
+
UnwrappingError = Class.new(Error)
|
16
|
+
|
17
|
+
Elem = type_member
|
18
|
+
ElemT = type_template { { upper: Object } }
|
19
|
+
|
20
|
+
abstract!
|
21
|
+
|
22
|
+
class << self
|
23
|
+
extend T::Sig
|
24
|
+
|
25
|
+
sig { params(value: ElemT).returns(Maybe::Some[ElemT]) }
|
26
|
+
# Returns a {Maybe::Some} wrapping the provided value.
|
27
|
+
#
|
28
|
+
# @param [Elem] value a value to wrap around a {Some} variant.
|
29
|
+
# @return [Some<Elem>]
|
30
|
+
def return(value)
|
31
|
+
Some.__send__(:new, T.unsafe(value))
|
32
|
+
end
|
33
|
+
alias some return
|
34
|
+
|
35
|
+
sig { returns(Maybe::None[NilClass]) }
|
36
|
+
# Returns a {Maybe::None}, a safer alternative to +nil+.
|
37
|
+
#
|
38
|
+
# @return [None]
|
39
|
+
def none
|
40
|
+
None.__send__(:new)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
sig { abstract.returns T::Boolean }
|
45
|
+
# Returns +true+ if instance is of the {Some} variant, or +false+ if it is
|
46
|
+
# of the {None} variant.
|
47
|
+
#
|
48
|
+
# @return [true] if instance is of the {Some} variant
|
49
|
+
# @return [false] if instance is of the {None} variant
|
50
|
+
def some?
|
51
|
+
end
|
52
|
+
|
53
|
+
sig { abstract.returns T::Boolean }
|
54
|
+
# Returns +true+ if instance is of the {None} variant, or +false+ if it is
|
55
|
+
# of the {Some} variant.
|
56
|
+
#
|
57
|
+
# @return [true] if instance is of the {None} variant
|
58
|
+
# @return [false] if instance is of the {Some} variant
|
59
|
+
def none?
|
60
|
+
end
|
61
|
+
|
62
|
+
sig { abstract.returns Elem }
|
63
|
+
# Returns the contained value if instance is of the {Some} variant, or
|
64
|
+
# raises {UnwrappingError} if it is of the {None} variant.
|
65
|
+
#
|
66
|
+
# @return [Elem]
|
67
|
+
# @raise [UnwrappingError] if instance is of the {None} variant
|
68
|
+
def value!
|
69
|
+
end
|
70
|
+
|
71
|
+
sig do
|
72
|
+
abstract.type_parameters(:Default)
|
73
|
+
.params(default: T.type_parameter(:Default))
|
74
|
+
.returns(T.any(Elem, T.type_parameter(:Default)))
|
75
|
+
end
|
76
|
+
# Returns the contained value if instance is of the {Some} variant, or the
|
77
|
+
# provided +default+ value if it is of the {None} variant.
|
78
|
+
#
|
79
|
+
# @param [Object] default the value to be used if the instance is of the
|
80
|
+
# {None} variant
|
81
|
+
# @return [Elem, Object]
|
82
|
+
def value_or(default)
|
83
|
+
end
|
84
|
+
|
85
|
+
sig do
|
86
|
+
abstract.type_parameters(:T)
|
87
|
+
.params(blk: T.proc.returns(T.type_parameter(:T)))
|
88
|
+
.returns(T.any(Elem, T.type_parameter(:T)))
|
89
|
+
end
|
90
|
+
# Returns the contained value if instance is of the {Some} variant, or runs
|
91
|
+
# the provided block and returns its result if it is of the {None} variant.
|
92
|
+
#
|
93
|
+
# @yieldreturn [Object]
|
94
|
+
# @return [Elem, yield]
|
95
|
+
def value_or_yield(&blk)
|
7
96
|
end
|
8
97
|
|
9
|
-
|
10
|
-
|
98
|
+
sig { abstract.returns(T.any(Elem, NilClass)) }
|
99
|
+
# Returns the contained value if instance is of the {Some} variant, or +nil+
|
100
|
+
# if it is of the {None} variant.
|
101
|
+
#
|
102
|
+
# @return [Elem, nil]
|
103
|
+
def value_or_nil
|
104
|
+
end
|
105
|
+
|
106
|
+
sig { abstract.params(_blk: T.untyped).returns(T.self_type) }
|
107
|
+
# Runs the provided block only if instance is of the {Some} variant,
|
108
|
+
# yielding the contained value.
|
109
|
+
# Always returns +self+.
|
110
|
+
#
|
111
|
+
# @yieldparam value [Elem] the contained value is passed to the block
|
112
|
+
# @return [self]
|
113
|
+
def and_then(&_blk)
|
114
|
+
end
|
115
|
+
|
116
|
+
sig { abstract.params(_blk: T.untyped).returns(T.self_type) }
|
117
|
+
# Runs the provided block only if instance is of the {None} variant,
|
118
|
+
# yielding no value to the block.
|
119
|
+
# Always returns +self+.
|
120
|
+
#
|
121
|
+
# @yield []
|
122
|
+
# @return [self]
|
123
|
+
def or_else(&_blk)
|
124
|
+
end
|
125
|
+
|
126
|
+
sig do
|
127
|
+
abstract.type_parameters(:T)
|
128
|
+
.params(
|
129
|
+
_blk: T.proc.params(arg0: Elem).returns(T.type_parameter(:T))
|
130
|
+
)
|
131
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
132
|
+
end
|
133
|
+
# If instance is of the {Some} variant, it passes the contained value to the
|
134
|
+
# block and returns a new {Some} instance containing the return value of the
|
135
|
+
# block; if instance is of the {None} variant, it returns itself.
|
136
|
+
#
|
137
|
+
# @yieldparam value [Elem] the contained value is passed to the block
|
138
|
+
# @yieldreturn [Object]
|
139
|
+
# @return [Maybe<yield>, None]
|
140
|
+
def map(&_blk)
|
141
|
+
end
|
142
|
+
|
143
|
+
sig do
|
144
|
+
abstract.type_parameters(:T)
|
145
|
+
.params(blk: T.proc.returns(T.type_parameter(:T)))
|
146
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
147
|
+
end
|
148
|
+
# If instance is of the {Some} variant, it returns itself; if instance is of
|
149
|
+
# the {None} variant it runs the block and returns a new {Some} instance
|
150
|
+
# containing the return value of the block.
|
151
|
+
#
|
152
|
+
# @yield []
|
153
|
+
# @yieldreturn [Object]
|
154
|
+
# @return [Maybe<yield>, self]
|
155
|
+
def map_none(&blk)
|
156
|
+
end
|
157
|
+
|
158
|
+
sig do
|
159
|
+
abstract.type_parameters(:T)
|
160
|
+
.params(
|
161
|
+
_blk: T.proc.params(arg0: Elem).returns(Maybe[T.type_parameter(:T)])
|
162
|
+
)
|
163
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
164
|
+
end
|
165
|
+
# If instance is of the {Some} variant, it yields the contained value to the
|
166
|
+
# block and it returns the return value of the block; if it is of the {None}
|
167
|
+
# variant, it returns itself.
|
168
|
+
#
|
169
|
+
# @yieldparam value [Elem] the contained value is passed to the block
|
170
|
+
# @yieldreturn [Maybe]
|
171
|
+
# @return [Maybe]
|
172
|
+
def bind(&_blk)
|
173
|
+
end
|
174
|
+
|
175
|
+
sig do
|
176
|
+
abstract.type_parameters(:T)
|
177
|
+
.params(blk: T.proc.returns(Maybe[T.type_parameter(:T)]))
|
178
|
+
.returns(T.any(Maybe[Elem], Maybe[T.type_parameter(:T)]))
|
179
|
+
end
|
180
|
+
# If instance is of the {None} variant, it runs the provided block and it
|
181
|
+
# returns its return value; if it is of the {Some} variant, it returns
|
182
|
+
# itself.
|
183
|
+
#
|
184
|
+
# @yield []
|
185
|
+
# @yieldreturn [Maybe]
|
186
|
+
# @return [Maybe]
|
187
|
+
def bind_none(&blk)
|
188
|
+
end
|
189
|
+
|
190
|
+
sig { abstract.params(other: T.untyped).returns(T::Boolean) }
|
191
|
+
# Returns +true+ if both instances are of the same variant, and the
|
192
|
+
# contained values are equal in the case of {Some}.
|
193
|
+
#
|
194
|
+
# @param [Maybe<Elem>] other
|
195
|
+
# @return [Boolean]
|
196
|
+
def ==(other)
|
11
197
|
end
|
12
198
|
end
|
199
|
+
# rubocop:enable Metrics/ClassLength
|
13
200
|
end
|
201
|
+
|
202
|
+
require_relative 'maybe/some'
|
203
|
+
require_relative 'maybe/none'
|
data/lib/muina/result/failure.rb
CHANGED
data/lib/muina/result/success.rb
CHANGED
data/lib/muina/result.rb
CHANGED
data/lib/muina/version.rb
CHANGED
data/lib/muina.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# typed: strict
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require '
|
4
|
-
loader = Zeitwerk::Loader.for_gem
|
5
|
-
loader.setup
|
4
|
+
require 'sorbet-runtime'
|
6
5
|
|
7
6
|
module Muina
|
7
|
+
# Top level error class for {Muina}
|
8
|
+
Error = Class.new(StandardError)
|
8
9
|
end
|
9
10
|
|
10
|
-
|
11
|
+
require_relative 'muina/maybe'
|
12
|
+
require_relative 'muina/result'
|
metadata
CHANGED
@@ -1,36 +1,79 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: muina
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- rodrigovilina
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: sorbet-runtime
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0.5'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
27
|
-
|
26
|
+
version: '0.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: lollipop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop-vaporyhumo
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: tapioca
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.16'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.16'
|
69
|
+
description: Monads and other stuff to help you write safer Ruby code.
|
28
70
|
email:
|
29
71
|
- roanvilina@gmail.com
|
30
72
|
executables: []
|
31
73
|
extensions: []
|
32
74
|
extra_rdoc_files: []
|
33
75
|
files:
|
76
|
+
- CHANGELOG.md
|
34
77
|
- LICENSE
|
35
78
|
- README.md
|
36
79
|
- lib/muina.rb
|
@@ -41,12 +84,12 @@ files:
|
|
41
84
|
- lib/muina/result/failure.rb
|
42
85
|
- lib/muina/result/success.rb
|
43
86
|
- lib/muina/version.rb
|
44
|
-
homepage: https://github.com/
|
87
|
+
homepage: https://github.com/rodrigovilina/muina
|
45
88
|
licenses:
|
46
89
|
- Unlicense
|
47
90
|
metadata:
|
48
|
-
homepage_uri: https://github.com/
|
49
|
-
changelog_uri: https://github.com/
|
91
|
+
homepage_uri: https://github.com/rodrigovilina/muina
|
92
|
+
changelog_uri: https://github.com/rodrigovilina/muina/blob/main/CHANGELOG.md
|
50
93
|
rubygems_mfa_required: 'true'
|
51
94
|
post_install_message:
|
52
95
|
rdoc_options: []
|
@@ -63,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
106
|
- !ruby/object:Gem::Version
|
64
107
|
version: '0'
|
65
108
|
requirements: []
|
66
|
-
rubygems_version: 3.5.
|
109
|
+
rubygems_version: 3.5.15
|
67
110
|
signing_key:
|
68
111
|
specification_version: 4
|
69
112
|
summary: Write safer Ruby code.
|