muina 0.2.7
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 +7 -0
- data/.github/workflows/main.yml +16 -0
- data/.gitignore +5 -0
- data/.mutant.yml +38 -0
- data/.rspec +4 -0
- data/.rubocop.yml +172 -0
- data/.ruby-version +1 -0
- data/.simplecov +14 -0
- data/CHANGELOG.md +38 -0
- data/Gemfile +34 -0
- data/Gemfile.lock +265 -0
- data/Guardfile +24 -0
- data/README.md +36 -0
- data/Rakefile +13 -0
- data/SECURITY.md +14 -0
- data/bin/bundle +114 -0
- data/bin/console +15 -0
- data/bin/flay +29 -0
- data/bin/flog +29 -0
- data/bin/guard +29 -0
- data/bin/irb +29 -0
- data/bin/lefthook +29 -0
- data/bin/mutant +29 -0
- data/bin/parlour +29 -0
- data/bin/rake +29 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bin/setup +8 -0
- data/bin/srb +29 -0
- data/bin/srb-rbi +29 -0
- data/bin/tapioca +29 -0
- data/exe/muina +11 -0
- data/lefthook.yml +39 -0
- data/lib/muina/action/params_factory.rb +17 -0
- data/lib/muina/action/step/command.rb +31 -0
- data/lib/muina/action/step/failure.rb +18 -0
- data/lib/muina/action/step/query.rb +31 -0
- data/lib/muina/action/step/result.rb +51 -0
- data/lib/muina/action/step.rb +13 -0
- data/lib/muina/action.rb +73 -0
- data/lib/muina/any.rb +7 -0
- data/lib/muina/classes.rb +7 -0
- data/lib/muina/module.rb +6 -0
- data/lib/muina/parameters.rb +7 -0
- data/lib/muina/params.rb +19 -0
- data/lib/muina/private_creation.rb +12 -0
- data/lib/muina/result/factory.rb +37 -0
- data/lib/muina/result/failure.rb +31 -0
- data/lib/muina/result/null.rb +25 -0
- data/lib/muina/result/success.rb +31 -0
- data/lib/muina/result.rb +17 -0
- data/lib/muina/service.rb +37 -0
- data/lib/muina/symbol_hash.rb +7 -0
- data/lib/muina/unit.rb +10 -0
- data/lib/muina/untyped_array.rb +7 -0
- data/lib/muina/untyped_hash.rb +7 -0
- data/lib/muina/value.rb +16 -0
- data/lib/muina/version.rb +7 -0
- data/lib/muina.rb +42 -0
- data/muina.gemspec +35 -0
- data/rbi/muina.rbi +268 -0
- data/sorbet/config +2 -0
- data/sorbet/rbi/gems/actionpack@6.1.4.rbi +5045 -0
- data/sorbet/rbi/gems/actionview@6.1.4.rbi +2416 -0
- data/sorbet/rbi/gems/activesupport@6.1.4.rbi +3778 -0
- data/sorbet/rbi/gems/ast@2.4.2.rbi +54 -0
- data/sorbet/rbi/gems/awesome_print@1.9.2.rbi +322 -0
- data/sorbet/rbi/gems/builder@3.2.4.rbi +8 -0
- data/sorbet/rbi/gems/byebug@11.1.3.rbi +18 -0
- data/sorbet/rbi/gems/coderay@1.1.3.rbi +8 -0
- data/sorbet/rbi/gems/colorize@0.8.1.rbi +39 -0
- data/sorbet/rbi/gems/commander@4.6.0.rbi +8 -0
- data/sorbet/rbi/gems/concurrent-ruby@1.1.9.rbi +2403 -0
- data/sorbet/rbi/gems/crass@1.0.6.rbi +123 -0
- data/sorbet/rbi/gems/diff-lcs@1.4.4.rbi +185 -0
- data/sorbet/rbi/gems/docile@1.4.0.rbi +54 -0
- data/sorbet/rbi/gems/erubi@1.10.0.rbi +36 -0
- data/sorbet/rbi/gems/erubis@2.7.0.rbi +8 -0
- data/sorbet/rbi/gems/faker@2.18.0.rbi +2469 -0
- data/sorbet/rbi/gems/ffi@1.15.3.rbi +8 -0
- data/sorbet/rbi/gems/flay@2.12.1.rbi +178 -0
- data/sorbet/rbi/gems/flog@4.6.4.rbi +70 -0
- data/sorbet/rbi/gems/formatador@0.3.0.rbi +8 -0
- data/sorbet/rbi/gems/guard-compat@1.2.1.rbi +49 -0
- data/sorbet/rbi/gems/guard-rspec@4.7.3.rbi +233 -0
- data/sorbet/rbi/gems/guard-rubocop@1.4.0.rbi +66 -0
- data/sorbet/rbi/gems/guard-shell@0.7.2.rbi +69 -0
- data/sorbet/rbi/gems/guard@2.18.0.rbi +617 -0
- data/sorbet/rbi/gems/highline@2.0.3.rbi +8 -0
- data/sorbet/rbi/gems/i18n@1.8.10.rbi +616 -0
- data/sorbet/rbi/gems/io-console@0.5.9.rbi +8 -0
- data/sorbet/rbi/gems/irb@1.3.6.rbi +452 -0
- data/sorbet/rbi/gems/lefthook@0.7.6.rbi +8 -0
- data/sorbet/rbi/gems/listen@3.6.0.rbi +476 -0
- data/sorbet/rbi/gems/loofah@2.10.0.rbi +223 -0
- data/sorbet/rbi/gems/lumberjack@1.2.8.rbi +431 -0
- data/sorbet/rbi/gems/method_source@1.0.0.rbi +8 -0
- data/sorbet/rbi/gems/minitest@5.14.4.rbi +344 -0
- data/sorbet/rbi/gems/mutant-license@0.1.1.1.4043027289354708743625974235631451632228.0.rbi +8 -0
- data/sorbet/rbi/gems/mutant-rspec@0.10.32.rbi +8 -0
- data/sorbet/rbi/gems/mutant@0.10.32.rbi +4154 -0
- data/sorbet/rbi/gems/nenv@0.3.0.rbi +88 -0
- data/sorbet/rbi/gems/nokogiri@1.11.7.rbi +1422 -0
- data/sorbet/rbi/gems/notiffany@0.1.3.rbi +331 -0
- data/sorbet/rbi/gems/parallel@1.20.1.rbi +113 -0
- data/sorbet/rbi/gems/parlour@6.0.1.rbi +1726 -0
- data/sorbet/rbi/gems/parser@3.0.2.0.rbi +1683 -0
- data/sorbet/rbi/gems/path_expander@1.1.0.rbi +24 -0
- data/sorbet/rbi/gems/polyfill@1.9.0.rbi +393 -0
- data/sorbet/rbi/gems/pry@0.14.1.rbi +8 -0
- data/sorbet/rbi/gems/racc@1.5.2.rbi +47 -0
- data/sorbet/rbi/gems/rack-test@1.1.0.rbi +272 -0
- data/sorbet/rbi/gems/rack@2.2.3.rbi +1618 -0
- data/sorbet/rbi/gems/rails-dom-testing@2.0.3.rbi +92 -0
- data/sorbet/rbi/gems/rails-html-sanitizer@1.3.0.rbi +183 -0
- data/sorbet/rbi/gems/rainbow@3.0.0.rbi +153 -0
- data/sorbet/rbi/gems/rake@13.0.6.rbi +808 -0
- data/sorbet/rbi/gems/rb-fsevent@0.11.0.rbi +8 -0
- data/sorbet/rbi/gems/rb-inotify@0.10.1.rbi +8 -0
- data/sorbet/rbi/gems/regexp_parser@2.1.1.rbi +1120 -0
- data/sorbet/rbi/gems/reline@0.2.6.rbi +662 -0
- data/sorbet/rbi/gems/rexml@3.2.5.rbi +672 -0
- data/sorbet/rbi/gems/rspec-core@3.10.1.rbi +2509 -0
- data/sorbet/rbi/gems/rspec-expectations@3.10.1.rbi +1574 -0
- data/sorbet/rbi/gems/rspec-mocks@3.10.2.rbi +1462 -0
- data/sorbet/rbi/gems/rspec-support@3.10.2.rbi +509 -0
- data/sorbet/rbi/gems/rspec@3.10.0.rbi +38 -0
- data/sorbet/rbi/gems/rubocop-ast@1.8.0.rbi +2194 -0
- data/sorbet/rbi/gems/rubocop-performance@1.11.4.rbi +899 -0
- data/sorbet/rbi/gems/rubocop-rake@0.6.0.rbi +118 -0
- data/sorbet/rbi/gems/rubocop-rspec@2.4.0.rbi +1805 -0
- data/sorbet/rbi/gems/rubocop-sorbet@0.6.2.rbi +288 -0
- data/sorbet/rbi/gems/rubocop@1.18.4.rbi +13197 -0
- data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +405 -0
- data/sorbet/rbi/gems/ruby_parser@3.16.0.rbi +4528 -0
- data/sorbet/rbi/gems/safe_type@1.1.1.rbi +157 -0
- data/sorbet/rbi/gems/sexp_processor@4.15.3.rbi +359 -0
- data/sorbet/rbi/gems/shellany@0.0.1.rbi +28 -0
- data/sorbet/rbi/gems/simplecov-html@0.12.3.rbi +89 -0
- data/sorbet/rbi/gems/simplecov@0.21.2.rbi +577 -0
- data/sorbet/rbi/gems/simplecov_json_formatter@0.1.3.rbi +8 -0
- data/sorbet/rbi/gems/sorbet-coerce@0.5.0.rbi +42 -0
- data/sorbet/rbi/gems/sorbet-rails@0.7.4.rbi +8 -0
- data/sorbet/rbi/gems/sorbet-struct-comparable@1.1.0.rbi +17 -0
- data/sorbet/rbi/gems/spoom@1.1.1.rbi +1193 -0
- data/sorbet/rbi/gems/tapioca@0.4.23.rbi +1826 -0
- data/sorbet/rbi/gems/thor@1.1.0.rbi +838 -0
- data/sorbet/rbi/gems/tzinfo@2.0.4.rbi +856 -0
- data/sorbet/rbi/gems/unicode-display_width@2.0.0.rbi +26 -0
- data/sorbet/rbi/gems/unparser@0.6.0.rbi +2037 -0
- data/sorbet/rbi/gems/zeitwerk@2.4.2.rbi +173 -0
- data/sorbet/rbi/todo.rbi +8 -0
- data/sorbet/rbi/typed_params.rbi +7 -0
- data/sorbet/tapioca/require.rb +16 -0
- metadata +269 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Muina
|
|
5
|
+
class Action
|
|
6
|
+
class Step < Value
|
|
7
|
+
# Final step of a successful Action
|
|
8
|
+
class Result < self
|
|
9
|
+
class Caller
|
|
10
|
+
class Successful < self
|
|
11
|
+
def initialize(action, result)
|
|
12
|
+
super()
|
|
13
|
+
@action = action
|
|
14
|
+
@result = result
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def call
|
|
18
|
+
@action.instance_variable_set(:@__result__, @result)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class Failed < self
|
|
23
|
+
def initialize(action, result)
|
|
24
|
+
super()
|
|
25
|
+
@action = action
|
|
26
|
+
@result = result
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def call
|
|
30
|
+
@action.instance_variable_set(:@__failure__, @result)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.for(action, step)
|
|
35
|
+
case result = Muina::Result() { action.instance_eval(&step) }
|
|
36
|
+
when Muina::Result::Success then Caller::Successful.new(action, result)
|
|
37
|
+
when Muina::Result::Failure then Caller::Failed.new(action, result)
|
|
38
|
+
else T.absurd(result)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def call(action = Object.new)
|
|
44
|
+
return if action.instance_variable_get(:@__failure__)
|
|
45
|
+
|
|
46
|
+
Caller.for(action, step).call
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/muina/action.rb
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Muina
|
|
5
|
+
# Two tracked result based operation
|
|
6
|
+
class Action
|
|
7
|
+
include T::Props
|
|
8
|
+
include T::Props::Constructor
|
|
9
|
+
|
|
10
|
+
class DoubleResultError < Error; end
|
|
11
|
+
|
|
12
|
+
class DoubleFailureError < Error; end
|
|
13
|
+
|
|
14
|
+
private_class_method :new
|
|
15
|
+
|
|
16
|
+
def self.steps
|
|
17
|
+
@steps ||= []
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.extract(params)
|
|
21
|
+
new(TypedParams[parameters].new.extract!(ParamsFactory.build(params)).serialize.symbolize_keys)
|
|
22
|
+
end
|
|
23
|
+
private_class_method :extract
|
|
24
|
+
|
|
25
|
+
def self.result(&blk)
|
|
26
|
+
raise DoubleResultError if @__result_set__
|
|
27
|
+
|
|
28
|
+
steps << Step::Result.new(step: blk)
|
|
29
|
+
|
|
30
|
+
@__result_set__ = true
|
|
31
|
+
end
|
|
32
|
+
private_class_method :result
|
|
33
|
+
|
|
34
|
+
def self.failure(&blk)
|
|
35
|
+
raise DoubleFailureError if @__failure_set__
|
|
36
|
+
|
|
37
|
+
steps << Step::Failure.new(step: blk)
|
|
38
|
+
|
|
39
|
+
@__failure_set__ = true
|
|
40
|
+
end
|
|
41
|
+
private_class_method :failure
|
|
42
|
+
|
|
43
|
+
def self.command(_name = nil, &blk)
|
|
44
|
+
steps << Step::Command.new(step: blk)
|
|
45
|
+
end
|
|
46
|
+
private_class_method :command
|
|
47
|
+
|
|
48
|
+
def self.query(name, type = T.untyped, &blk)
|
|
49
|
+
const name, type
|
|
50
|
+
steps << Step::Query.new(name: name, step: blk)
|
|
51
|
+
end
|
|
52
|
+
private_class_method :query
|
|
53
|
+
|
|
54
|
+
def self.parameters(&blk)
|
|
55
|
+
@parameters ||= Class.new(T::Struct)
|
|
56
|
+
parameters.instance_eval(&blk) if blk
|
|
57
|
+
instance_eval(&blk) if blk
|
|
58
|
+
@parameters
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.call(hash = {})
|
|
62
|
+
extract(hash).__send__(:perform)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
private
|
|
66
|
+
|
|
67
|
+
def perform
|
|
68
|
+
self.class.steps.each { |step| step.call(self) }
|
|
69
|
+
|
|
70
|
+
@__result__ || @__failure__ || Result::Null()
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
data/lib/muina/any.rb
ADDED
data/lib/muina/module.rb
ADDED
data/lib/muina/params.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Muina
|
|
5
|
+
# Typesafe parameters with extraction from ActionController::Parameters
|
|
6
|
+
class Params
|
|
7
|
+
include T::Props
|
|
8
|
+
include T::Props::Constructor
|
|
9
|
+
|
|
10
|
+
def self.extract(params)
|
|
11
|
+
params = ActionController::Parameters.new(params) if params.instance_of?(Hash)
|
|
12
|
+
TypedParams[self].new.extract!(params)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.<(other)
|
|
16
|
+
super || T::Struct <= other
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Muina
|
|
5
|
+
# Include this module to make `.allocate` and `.new` private
|
|
6
|
+
module PrivateCreation
|
|
7
|
+
def self.included(klass)
|
|
8
|
+
klass.private_class_method :allocate
|
|
9
|
+
klass.private_class_method :new
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Muina
|
|
5
|
+
# Result Monad
|
|
6
|
+
class Result < Value
|
|
7
|
+
# Typed Results Factory.
|
|
8
|
+
class Factory < T::Struct
|
|
9
|
+
prop :success_klass, T.any(Classes, T::Types::Base)
|
|
10
|
+
prop :error_klass, T.any(Classes, T::Types::Base)
|
|
11
|
+
|
|
12
|
+
def success(value)
|
|
13
|
+
success_subclass.__send__(:new, value: value)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def failure(error)
|
|
17
|
+
failure_subclass.__send__(:new, error: error)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def success_subclass
|
|
23
|
+
klass_factory(Success, :value, success_klass)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def failure_subclass
|
|
27
|
+
klass_factory(Failure, :error, error_klass)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def klass_factory(klass, symbol, sklass)
|
|
31
|
+
iklass = T.unsafe(Class.new(klass)) # rubocop:disable Sorbet/ForbidTUnsafe
|
|
32
|
+
iklass.const symbol, sklass, override: true
|
|
33
|
+
iklass.__send__(:private, symbol)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Muina
|
|
5
|
+
class Result < Value
|
|
6
|
+
# Right(wrong) side of the Result Monad
|
|
7
|
+
class Failure < self
|
|
8
|
+
class ValueCalledOnFailureError < Error; end
|
|
9
|
+
|
|
10
|
+
const :error, T.untyped
|
|
11
|
+
private :error
|
|
12
|
+
|
|
13
|
+
def value!
|
|
14
|
+
raise ValueCalledOnFailureError
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def error!
|
|
18
|
+
error
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def and_then(&_blk)
|
|
22
|
+
self
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def or_else(&blk)
|
|
26
|
+
blk[error] if blk
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Muina
|
|
5
|
+
class Result < Value
|
|
6
|
+
# Private null type for the Result Monad
|
|
7
|
+
class Null < self
|
|
8
|
+
def value!
|
|
9
|
+
raise Error
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def error!
|
|
13
|
+
raise Error
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def and_then(&_blk)
|
|
17
|
+
self
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def or_else(&_blk)
|
|
21
|
+
self
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Muina
|
|
5
|
+
class Result < Value
|
|
6
|
+
# Left(correct) side of the Result Monad
|
|
7
|
+
class Success < self
|
|
8
|
+
class ErrorCalledOnSuccessError < Error; end
|
|
9
|
+
|
|
10
|
+
const :value, T.untyped
|
|
11
|
+
private :value
|
|
12
|
+
|
|
13
|
+
def value!
|
|
14
|
+
value
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def error!
|
|
18
|
+
raise ErrorCalledOnSuccessError
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def and_then(&blk)
|
|
22
|
+
blk[value] if blk
|
|
23
|
+
self
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def or_else(&_blk)
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/muina/result.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Muina
|
|
5
|
+
# Result Monad
|
|
6
|
+
class Result < Value
|
|
7
|
+
include PrivateCreation
|
|
8
|
+
|
|
9
|
+
def self.Null # rubocop:disable Naming/MethodName
|
|
10
|
+
Null.__send__(:new)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.[](success_klass, error_klass)
|
|
14
|
+
Factory.new(success_klass: success_klass, error_klass: error_klass)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Muina
|
|
5
|
+
# Simple Service Object compatible with MiniService::Base
|
|
6
|
+
class Service
|
|
7
|
+
include T::Props
|
|
8
|
+
include T::Props::Constructor
|
|
9
|
+
include PrivateCreation
|
|
10
|
+
|
|
11
|
+
def self.inherited(subklass) # rubocop:disable Metrics/MethodLength
|
|
12
|
+
super
|
|
13
|
+
# :nocov:
|
|
14
|
+
TracePoint.trace(:end) do |t|
|
|
15
|
+
if subklass < self && !subklass.instance_methods(false).include?(:perform) # rubocop:disable Style/MissingElse
|
|
16
|
+
Logger.new($stdout).fatal "#{subklass}#perfrom is not implemented"
|
|
17
|
+
end
|
|
18
|
+
t.disable
|
|
19
|
+
end
|
|
20
|
+
# :nocov:
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.call(hash = {})
|
|
24
|
+
new(hash).__send__(:perform)
|
|
25
|
+
end
|
|
26
|
+
class << self; alias_method :[], :call; end
|
|
27
|
+
|
|
28
|
+
def self.arguments(*args, **opts)
|
|
29
|
+
args.each { |arg| const arg, T.untyped }
|
|
30
|
+
opts.each { |key, value| const key, T.untyped, default: value }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def perform
|
|
34
|
+
raise NotImplementedError, "Please implement the #{self.class}#perform method"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/muina/unit.rb
ADDED
data/lib/muina/value.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module Muina
|
|
5
|
+
# Immutable Value Object parent class
|
|
6
|
+
class Value
|
|
7
|
+
include T::Props
|
|
8
|
+
include T::Props::Constructor
|
|
9
|
+
include T::Struct::ActsAsComparable
|
|
10
|
+
|
|
11
|
+
def initialize(hash = {})
|
|
12
|
+
super(hash)
|
|
13
|
+
freeze
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/muina.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Load dependencies
|
|
5
|
+
require 'action_controller'
|
|
6
|
+
require 'action_controller/metal/exceptions'
|
|
7
|
+
require 'sorbet-runtime'
|
|
8
|
+
require 'sorbet-rails/typed_params'
|
|
9
|
+
require 'sorbet-struct-comparable'
|
|
10
|
+
|
|
11
|
+
# Require Module monkeypatch
|
|
12
|
+
require 'muina/module'
|
|
13
|
+
|
|
14
|
+
# Setup zeitwork loader
|
|
15
|
+
require 'zeitwerk'
|
|
16
|
+
loader = Zeitwerk::Loader.for_gem
|
|
17
|
+
module_ext = "#{__dir__}/muina/module.rb"
|
|
18
|
+
loader.ignore(module_ext)
|
|
19
|
+
loader.setup
|
|
20
|
+
|
|
21
|
+
# Top level module
|
|
22
|
+
module Muina
|
|
23
|
+
class Error < StandardError; end
|
|
24
|
+
|
|
25
|
+
def self.Success(value) # rubocop:disable Naming/MethodName
|
|
26
|
+
Result::Success.__send__(:new, value: value)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.Failure(error) # rubocop:disable Naming/MethodName
|
|
30
|
+
Result::Failure.__send__(:new, error: error)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.Result(&blk) # rubocop:disable Naming/MethodName
|
|
34
|
+
Success(blk[])
|
|
35
|
+
rescue StandardError => e
|
|
36
|
+
Failure(e)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
M = Muina
|
|
40
|
+
|
|
41
|
+
# Eager load all code
|
|
42
|
+
loader.eager_load
|
data/muina.gemspec
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# typed: strict
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative 'lib/muina/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = 'muina'
|
|
8
|
+
spec.version = Muina::VERSION
|
|
9
|
+
spec.authors = ['vaporyhumo']
|
|
10
|
+
spec.email = ['roanvilina@gmail.com']
|
|
11
|
+
|
|
12
|
+
spec.summary = 'Rails and Sorbet compatible framework'
|
|
13
|
+
spec.description = 'Useful parent classes for the Rails missing parts'
|
|
14
|
+
spec.homepage = 'https://github.com/vaporyhumo/muina'
|
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.6.0')
|
|
16
|
+
|
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
18
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
|
19
|
+
spec.metadata['changelog_uri'] = spec.homepage
|
|
20
|
+
|
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
|
25
|
+
end
|
|
26
|
+
spec.bindir = 'exe'
|
|
27
|
+
spec.executables = ['muina']
|
|
28
|
+
spec.require_paths = ['lib']
|
|
29
|
+
|
|
30
|
+
spec.add_dependency 'actionpack'
|
|
31
|
+
spec.add_dependency 'sorbet-rails'
|
|
32
|
+
spec.add_dependency 'sorbet-runtime'
|
|
33
|
+
spec.add_dependency 'sorbet-struct-comparable'
|
|
34
|
+
spec.add_dependency 'zeitwerk'
|
|
35
|
+
end
|