Skip to content

Commit 5a559bd

Browse files
committed
feat: add missing methods, add sig
1 parent e5b0a8a commit 5a559bd

8 files changed

Lines changed: 690 additions & 10 deletions

File tree

Rakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ RuboCop::RakeTask.new do |task|
1010
task.plugins << "rubocop-rspec"
1111
end
1212

13-
task default: [:spec, :rubocop]
13+
task default: [:spec]

Steepfile

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# D = Steep::Diagnostic
2+
3+
target :lib do
4+
signature "sig"
5+
6+
check "lib" # Directory name
7+
# ignore "lib/templates/*.rb"
8+
9+
# library "pathname" # Standard libraries
10+
# library "strong_json" # Gems
11+
12+
# configure_code_diagnostics(D::Ruby.default) # `default` diagnostics setting (applies by default)
13+
# configure_code_diagnostics(D::Ruby.strict) # `strict` diagnostics setting
14+
# configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
15+
# configure_code_diagnostics(D::Ruby.silent) # `silent` diagnostics setting
16+
# configure_code_diagnostics do |hash| # You can setup everything yourself
17+
# hash[D::Ruby::NoMethod] = :information
18+
# end
19+
end
20+
21+
# target :test do
22+
# unreferenced! # Skip type checking the `lib` code when types in `test` target is changed
23+
# signature "sig/test" # Put RBS files for tests under `sig/test`
24+
# check "test" # Type check Ruby scripts under `test`
25+
#
26+
# configure_code_diagnostics(D::Ruby.lenient) # Weak type checking for test code
27+
#
28+
# # library "pathname" # Standard libraries
29+
# end

lib/rs/option.rb

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,107 @@ def unwrap_or(default)
4848
def unwrap_or_else(&block)
4949
is_some ? @value : block.call
5050
end
51+
52+
def map(value_type, &block)
53+
if is_some
54+
Some[value_type] { block.call(@value) }
55+
else
56+
None[value_type]
57+
end
58+
end
59+
60+
def map_or(default, &block)
61+
is_some ? block.call(@value) : default
62+
end
63+
64+
def map_or_else(default, &block)
65+
is_some ? block.call(@value) : default.call
66+
end
67+
68+
def ok_or(error)
69+
if is_some
70+
Ok[@value_type, error.class] { @value }
71+
else
72+
Err[@value_type, error.class] { error }
73+
end
74+
end
75+
76+
def ok_or_else(&block)
77+
error = block.call
78+
if is_some
79+
Ok[@value_type, error.class] { @value }
80+
else
81+
Err[@value_type, error.class] { error }
82+
end
83+
end
84+
85+
def and(other)
86+
is_some ? other : None[other.value_type]
87+
end
88+
89+
def and_then(value_type, &block)
90+
is_some ? block.call(@value) : None[value_type]
91+
end
92+
93+
def select(&block)
94+
if is_some
95+
block.call(@value) ? self : None[@value_type]
96+
else
97+
None[@value_type]
98+
end
99+
end
100+
101+
def or(other)
102+
if is_some
103+
self
104+
else
105+
other
106+
end
107+
end
108+
109+
def or_else(&block)
110+
is_some ? self : block.call
111+
end
112+
113+
def xor(other)
114+
case [is_some, other.is_some]
115+
when [true, false]
116+
self
117+
when [false, true]
118+
other
119+
when [true, true]
120+
None[@value_type]
121+
else
122+
None[@value_type]
123+
end
124+
end
125+
126+
def tap(&block)
127+
if is_some
128+
value = @value
129+
block.call(value)
130+
end
131+
self
132+
end
133+
134+
def self.from(value_type, &block)
135+
Some[value_type, &block]
136+
end
137+
138+
def self.from?(value_type, &block)
139+
value = block.call
140+
if value == nil
141+
None[value_type]
142+
else
143+
Some[value_type] { value }
144+
end
145+
end
146+
147+
def self.from!(value_type, &block)
148+
Some[value_type, &block]
149+
rescue StandardError
150+
None[value_type]
151+
end
51152
end
52153
end
53154

lib/rs/result.rb

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,98 @@ def expect_err(msg)
6666
def unwrap_err
6767
is_ok ? raise(UnwrapErrOnOk.new("called unwrap_err() on an Ok value: #{@value}")) : @error
6868
end
69+
70+
def map(value_type, &block)
71+
if is_ok
72+
Ok[value_type, @error_type] { block.call(@value) }
73+
else
74+
Err[value_type, @error_type] { @error }
75+
end
76+
end
77+
78+
def map_or(default, &block)
79+
is_ok ? block.call(@value) : default
80+
end
81+
82+
def map_or_else(default, &block)
83+
is_ok ? block.call(@value) : default.call(@error)
84+
end
85+
86+
def map_err(error_type, &block)
87+
if is_ok
88+
Ok[@value_type, error_type] { @value }
89+
else
90+
Err[@value_type, error_type] { block.call(@error) }
91+
end
92+
end
93+
94+
def tap(&block)
95+
if is_ok
96+
value = @value
97+
block.call(value)
98+
end
99+
self
100+
end
101+
102+
def inspect_err(&block)
103+
if is_err
104+
error = @error
105+
block.call(error)
106+
end
107+
self
108+
end
109+
110+
def and(other)
111+
if is_ok
112+
other
113+
else
114+
Err[other.value_type, @error_type] { @error }
115+
end
116+
end
117+
118+
def and_then(value_type, &block)
119+
if is_ok
120+
block.call(@value)
121+
else
122+
Err[value_type, @error_type] { @error }
123+
end
124+
end
125+
126+
def or(other)
127+
if is_ok
128+
Ok[@value_type, other.error_type] { @value }
129+
else
130+
other
131+
end
132+
end
133+
134+
def or_else(error_type, &block)
135+
if is_ok
136+
Ok[@value_type, error_type] { @value }
137+
else
138+
block.call(@error)
139+
end
140+
end
141+
142+
def self.from_or(value_type, error, &block)
143+
Ok[value_type, error.class] { block.call }
144+
end
145+
146+
def self.from_or?(value_type, error, &block)
147+
value = block.call
148+
if value == nil
149+
Err[value_type, error.class] { error }
150+
else
151+
Ok[value_type, error.class] { value }
152+
end
153+
end
154+
155+
def self.from_or!(value_type, error, &block)
156+
value = block.call
157+
Ok[value_type, error.class] { value }
158+
rescue StandardError
159+
Err[value_type, error.class] { error }
160+
end
69161
end
70162
end
71163

sig/rs/option.rbs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
module Rs
2+
# https://doc.rust-lang.org/std/option/index.html
3+
# https://doc.rust-lang.org/std/option/enum.Option.html
4+
# https://doc.rust-lang.org/src/core/option.rs.html
5+
class Option
6+
class TypeError < StandardError
7+
def initialize: (untyped value_type) -> void
8+
end
9+
10+
class TypeNilClass < StandardError
11+
end
12+
13+
class TypeMismatch < StandardError
14+
end
15+
16+
class WrapNil < StandardError
17+
end
18+
19+
class UnwrapNone < StandardError
20+
end
21+
22+
def is_some: () -> untyped
23+
24+
def is_some_and: () { (?) -> untyped } -> (untyped | false)
25+
26+
def is_none: () -> untyped
27+
28+
def is_none_or: () { (?) -> untyped } -> (true | untyped)
29+
30+
def expect: (untyped msg) -> untyped
31+
32+
def unwrap: () -> untyped
33+
34+
def unwrap_or: (untyped default) -> untyped
35+
36+
def unwrap_or_else: () { (?) -> untyped } -> untyped
37+
38+
def map: (untyped value_type) { (?) -> untyped } -> untyped
39+
40+
def map_or: (untyped default) { (?) -> untyped } -> untyped
41+
42+
def map_or_else: (untyped default) { (?) -> untyped } -> untyped
43+
44+
def ok_or: (untyped error) -> untyped
45+
46+
def ok_or_else: () { (?) -> untyped } -> untyped
47+
48+
def and: (untyped other) -> untyped
49+
50+
def and_then: (untyped value_type) { (?) -> untyped } -> untyped
51+
52+
def select: () { (?) -> untyped } -> (self | untyped | untyped)
53+
54+
def or: (untyped other) -> (self | untyped)
55+
56+
def or_else: () { (?) -> untyped } -> (self | untyped)
57+
58+
def xor: (untyped other) -> untyped
59+
60+
def tap: () { (?) -> untyped } -> self
61+
62+
def self.from: (untyped value_type) { (?) -> untyped } -> untyped
63+
64+
def self.from?: (untyped value_type) { (?) -> untyped } -> untyped
65+
66+
def self.from!: (untyped value_type) { (?) -> untyped } -> untyped
67+
end
68+
end
69+
70+
class Some < Rs::Option
71+
@value: untyped
72+
73+
@value_type: untyped
74+
75+
attr_reader value_type: untyped
76+
77+
def self.[]: (untyped value_type) { (?) -> untyped } -> untyped
78+
79+
def inspect: () -> ::String
80+
81+
def ==: (untyped other) -> untyped
82+
83+
def initialize: (untyped value) -> void
84+
end
85+
86+
class None < Rs::Option
87+
@value_type: untyped
88+
89+
attr_reader value_type: untyped
90+
91+
def self.[]: (untyped value_type) -> untyped
92+
93+
def inspect: () -> ::String
94+
95+
def ==: (untyped other) -> untyped
96+
97+
def initialize: (?untyped value_type) -> void
98+
end

0 commit comments

Comments
 (0)