muina 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +75 -0
- data/README.md +44 -0
- data/lib/muina/maybe/none.rb +75 -8
- data/lib/muina/maybe/some.rb +74 -7
- data/lib/muina/maybe.rb +186 -1
- data/lib/muina/result.rb +3 -0
- data/lib/muina/version.rb +3 -1
- data/lib/muina.rb +5 -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
|
+
[![Gem Version](http://img.shields.io/gem/v/muina.svg)][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,63 +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)
|
18
|
+
sig { void }
|
7
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
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
|
|
61
|
+
sig { override.returns(T.any(Elem, NilClass)) }
|
62
|
+
# (see Maybe#value_or_nil)
|
31
63
|
def value_or_nil; end
|
32
64
|
|
33
|
-
|
65
|
+
sig { override.params(_blk: T.untyped).returns(T.self_type) }
|
66
|
+
# (see Maybe#and_then)
|
67
|
+
def and_then(&_blk)
|
34
68
|
self
|
35
69
|
end
|
36
70
|
|
37
|
-
|
71
|
+
sig { override.params(_blk: T.untyped).returns(T.self_type) }
|
72
|
+
# (see Maybe#or_else)
|
73
|
+
def or_else(&_blk)
|
38
74
|
yield
|
39
75
|
self
|
40
76
|
end
|
41
77
|
|
42
|
-
|
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)
|
43
87
|
self
|
44
88
|
end
|
45
89
|
|
46
|
-
|
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)
|
47
97
|
Maybe.return yield
|
48
98
|
end
|
49
99
|
|
50
|
-
|
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)
|
51
109
|
self
|
52
110
|
end
|
53
111
|
|
54
|
-
|
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)
|
55
119
|
yield
|
56
120
|
end
|
57
121
|
|
122
|
+
sig { override.params(other: T.untyped).returns(T::Boolean) }
|
123
|
+
# (see Maybe#==)
|
58
124
|
def ==(other)
|
59
|
-
self.class
|
125
|
+
other.instance_of?(self.class)
|
60
126
|
end
|
61
127
|
end
|
128
|
+
# rubocop:enable Metrics/ClassLength
|
62
129
|
end
|
63
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
|
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
|
+
|
6
17
|
private_class_method(:new)
|
18
|
+
sig { params(value: Elem).void }
|
7
19
|
def initialize(value) # rubocop:disable Lint/MissingSuper
|
8
20
|
@value = value
|
9
21
|
freeze
|
10
22
|
end
|
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
|
|
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
|
24
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,18 +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
|
10
|
+
extend T::Sig
|
11
|
+
extend T::Helpers
|
12
|
+
extend T::Generic
|
13
|
+
|
14
|
+
# Raised when trying to unwrap a {None} value
|
5
15
|
UnwrappingError = Class.new(Error)
|
6
16
|
|
17
|
+
Elem = type_member
|
18
|
+
ElemT = type_template { { upper: Object } }
|
19
|
+
|
20
|
+
abstract!
|
21
|
+
|
7
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>]
|
8
30
|
def return(value)
|
9
|
-
Some.__send__(:new, value)
|
31
|
+
Some.__send__(:new, T.unsafe(value))
|
10
32
|
end
|
11
33
|
alias some return
|
12
34
|
|
35
|
+
sig { returns(Maybe::None[NilClass]) }
|
36
|
+
# Returns a {Maybe::None}, a safer alternative to +nil+.
|
37
|
+
#
|
38
|
+
# @return [None]
|
13
39
|
def none
|
14
40
|
None.__send__(:new)
|
15
41
|
end
|
16
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)
|
96
|
+
end
|
97
|
+
|
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)
|
197
|
+
end
|
17
198
|
end
|
199
|
+
# rubocop:enable Metrics/ClassLength
|
18
200
|
end
|
201
|
+
|
202
|
+
require_relative 'maybe/some'
|
203
|
+
require_relative 'maybe/none'
|
data/lib/muina/result.rb
CHANGED
data/lib/muina/version.rb
CHANGED
data/lib/muina.rb
CHANGED
@@ -1,11 +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
8
|
Error = Class.new(StandardError)
|
9
9
|
end
|
10
10
|
|
11
|
-
|
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.
|