loading
Generated 2025-01-21T09:49:06+00:00

All Files ( 96.42% covered at 15.81 hits/line )

10 files in total.
558 relevant lines, 538 lines covered and 20 lines missed. ( 96.42% )
39 total branches, 22 branches covered and 17 branches missed. ( 56.41% )
File % covered Lines Relevant Lines Lines covered Lines missed Avg. Hits / Line Branch Coverage Branches Covered branches Missed branches
lib/mangrove.rb 100.00 % 13 7 7 0 1.00 100.00 % 0 0 0
lib/mangrove/control_flow/control_signal.rb 100.00 % 16 8 8 0 1.13 100.00 % 0 0 0
lib/mangrove/enum.rb 100.00 % 101 7 7 0 1.14 100.00 % 0 0 0
lib/mangrove/option.rb 95.87 % 210 121 116 5 1.64 50.00 % 8 4 4
lib/mangrove/option/control_signal.rb 94.12 % 33 17 16 1 1.71 50.00 % 2 1 1
lib/mangrove/result.rb 98.69 % 582 305 301 4 3.29 73.33 % 15 11 4
lib/mangrove/result/control_signal.rb 94.12 % 33 17 16 1 1.82 50.00 % 2 1 1
lib/mangrove/result/ext.rb 100.00 % 18 8 8 0 2.00 100.00 % 0 0 0
lib/tapioca/dsl/compilers/mangrove_enum.rb 80.85 % 89 47 38 9 59.19 40.00 % 10 4 6
lib/tapioca/dsl/compilers/mangrove_result_ext.rb 100.00 % 40 21 21 0 225.76 50.00 % 2 1 1

lib/mangrove.rb

100.0% lines covered

100.0% branches covered

7 relevant lines. 7 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # typed: strict
  2. # frozen_string_literal: true
  3. 1 require "sorbet-runtime"
  4. 1 require_relative "mangrove/version"
  5. 1 require_relative "mangrove/option"
  6. 1 require_relative "mangrove/result"
  7. 1 require_relative "mangrove/enum"
  8. 1 require_relative "mangrove/control_flow/control_signal"
  9. # Mangrove
  10. 1 module Mangrove; end

lib/mangrove/control_flow/control_signal.rb

100.0% lines covered

100.0% branches covered

8 relevant lines. 8 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # typed: strict
  2. # frozen_string_literal: true
  3. 1 module Mangrove
  4. 1 module ControlFlow
  5. 1 module ControlSignal
  6. 1 extend T::Sig
  7. 1 extend T::Helpers
  8. 1 interface!
  9. 2 sig { abstract.returns(T.untyped) }
  10. 1 def inner_value; end
  11. end
  12. end
  13. end

lib/mangrove/enum.rb

100.0% lines covered

100.0% branches covered

7 relevant lines. 7 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # typed: strict
  2. # frozen_string_literal: true
  3. require "sorbet-runtime"
  4. module Mangrove
  5. class EnumVariantsScope
  6. extend ::T::Sig
  7. extend ::T::Helpers
  8. sig { params(parent: T::Class[T.anything]).void }
  9. def initialize(parent)
  10. @parent = parent
  11. end
  12. sig { params(block: T.proc.void).void }
  13. def call(&block)
  14. instance_eval(&block)
  15. end
  16. sig { params(variant: T::Class[T.anything], inner_type: T.untyped).void }
  17. def variant(variant, inner_type)
  18. variant.instance_variable_set(:@__mangrove__enum_inner_type, inner_type)
  19. end
  20. end
  21. private_constant :EnumVariantsScope
  22. module Enum
  23. extend ::T::Sig
  24. extend ::T::Helpers
  25. requires_ancestor { Module }
  26. sig { params(block: T.proc.bind(EnumVariantsScope).void).void }
  27. def variants(&block)
  28. receiver = block.send(:binding).receiver
  29. outer_code = <<~RUBY
  30. def self.const_missing(id)
  31. code = <<~NESTED_RUBY
  32. class \#{id} < \#{caller.send(:binding).receiver.name}
  33. def initialize(inner)
  34. @inner = T.let(inner, self.class.instance_variable_get(:@__mangrove__enum_inner_type))
  35. end
  36. def inner
  37. @inner
  38. end
  39. def as_super
  40. T.cast(self, \#{caller.send(:binding).receiver.name})
  41. end
  42. def ==(other)
  43. other.is_a?(self.class) && other.inner == @inner
  44. end
  45. end
  46. NESTED_RUBY
  47. class_eval(code, __FILE__, __LINE__ + 1)
  48. class_eval(id.to_s, __FILE__, __LINE__ + 1)
  49. end
  50. RUBY
  51. original_const_missing = receiver.method(:const_missing)
  52. receiver.class_eval(outer_code, __FILE__, __LINE__ + 1)
  53. 1 EnumVariantsScope.new(receiver).call(&block)
  54. 1
  55. # Mark as sealed hear because we can not define classes in const_missing after marking as sealed
  56. 1 receiver.send(:eval, "sealed!", nil, __FILE__, __LINE__)
  57. variants = constants.filter_map { |variant_name|
  58. maybe_variant = receiver.const_get(variant_name, false)
  59. if maybe_variant.instance_variable_defined?(:@__mangrove__enum_inner_type)
  60. maybe_variant
  61. end
  62. }
  63. receiver.class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
  64. 1 @sorbet_sealed_module_all_subclasses = #{variants} # @sorbet_sealed_module_all_subclasses = #{variants}
  65. RUBY
  66. # Bring back the original const_missing
  67. receiver.define_singleton_method(:const_missing, original_const_missing)
  68. end
  69. 1 sig { params(receiver: T::Class[T.anything]).void }
  70. 2 def self.extended(receiver)
  71. 1 code = <<~RUBY
  72. extend T::Sig
  73. extend T::Helpers
  74. abstract!
  75. RUBY
  76. receiver.class_eval(code)
  77. end
  78. end
  79. end

lib/mangrove/option.rb

95.87% lines covered

50.0% branches covered

121 relevant lines. 116 lines covered and 5 lines missed.
8 total branches, 4 branches covered and 4 branches missed.
    
  1. # typed: strict
  2. # frozen_string_literal: true
  3. 1 require_relative "option/control_signal"
  4. 1 require_relative "result"
  5. 1 module Mangrove
  6. # Option is a type that represents either some value (`Some`) or no value (`None`).
  7. 1 module Option
  8. 1 extend T::Sig
  9. 1 extend T::Generic
  10. 1 extend T::Helpers
  11. 1 include Kernel
  12. 1 sealed!
  13. 1 interface!
  14. 1 InnerType = type_member
  15. 1 class << self
  16. 1 extend ::T::Sig
  17. 2 sig { type_parameters(:InnerType).params(nilable: T.nilable(T.type_parameter(:InnerType))).returns(Mangrove::Option[T.type_parameter(:InnerType)]) }
  18. 1 def from_nilable(nilable)
  19. 2 case nilable
  20. when: 1 when NilClass
  21. 1 Mangrove::Option::None.new
  22. else: 1 else
  23. 1 Mangrove::Option::Some.new(nilable)
  24. end
  25. end
  26. end
  27. # Option::Some
  28. 1 class Some
  29. 1 extend T::Sig
  30. 1 extend T::Generic
  31. 1 extend T::Helpers
  32. 1 include Option
  33. 1 InnerType = type_member
  34. 2 sig { params(inner: InnerType).void }
  35. 1 def initialize(inner)
  36. 28 @inner = T.let(inner, InnerType)
  37. end
  38. 2 sig { override.params(other: BasicObject).returns(T::Boolean) }
  39. 1 def ==(other)
  40. 7 case other
  41. when: 7 when Option::Some
  42. 7 other.instance_variable_get(:@inner) == @inner
  43. when: 0 when Option::None
  44. false
  45. else # rubocop:disable Lint/DuplicateBranch
  46. else: 0 # Because == is defined on BasicObject, we can't be sure that `other` is an Option
  47. false
  48. end
  49. end
  50. 1 sig { returns(InnerType) }
  51. 1 def unwrap
  52. @inner
  53. end
  54. 2 sig { override.params(_default: InnerType).returns(InnerType) }
  55. 1 def unwrap_or(_default)
  56. 1 @inner
  57. end
  58. 2 sig { override.returns(InnerType) }
  59. 1 def unwrap!
  60. 2 @inner
  61. end
  62. 2 sig { override.params(_message: String).returns(InnerType) }
  63. 1 def expect!(_message)
  64. 2 @inner
  65. end
  66. 2 sig { override.params(_block: T.proc.returns(T.untyped)).returns(InnerType) }
  67. 1 def expect_with!(&_block)
  68. 2 @inner
  69. end
  70. 2 sig { override.returns(T::Boolean) }
  71. 1 def some? = true
  72. 2 sig { override.returns(T::Boolean) }
  73. 1 def none? = false
  74. 2 sig { override.type_parameters(:NewInnerType).params(block: T.proc.params(inner: InnerType).returns(Option[T.type_parameter(:NewInnerType)])).returns(::Mangrove::Option[T.type_parameter(:NewInnerType)]) }
  75. 1 def map(&block)
  76. 2 block.call(@inner)
  77. end
  78. 2 sig { override.params(_default: Option[InnerType]).returns(Option[InnerType]) }
  79. 1 def or(_default)
  80. 2 self
  81. end
  82. 2 sig { override.type_parameters(:ErrType).params(_err: T.type_parameter(:ErrType)).returns(Mangrove::Result[InnerType, T.type_parameter(:ErrType)]) }
  83. 1 def transpose(_err)
  84. 1 Result::Ok.new(@inner)
  85. end
  86. 1 private
  87. 1 sig { returns(InnerType) }
  88. 1 attr_reader :inner
  89. end
  90. # Option::None
  91. 1 class None
  92. 1 extend T::Sig
  93. 1 extend T::Generic
  94. 1 extend T::Helpers
  95. 1 include Option
  96. 1 InnerType = type_member
  97. 2 sig { override.params(other: BasicObject).returns(T::Boolean) }
  98. 1 def ==(other)
  99. 3 case other
  100. when: 0 when Option::Some
  101. false
  102. when: 3 when Option::None
  103. 3 true
  104. else # rubocop:disable Lint/DuplicateBranch
  105. else: 0 # Because == is defined on BasicObject, we can't be sure that `other` is an Option
  106. false
  107. end
  108. end
  109. 2 sig { override.params(default: InnerType).returns(InnerType) }
  110. 1 def unwrap_or(default)
  111. 1 default
  112. end
  113. 2 sig { override.returns(InnerType) }
  114. 1 def unwrap!
  115. 1 raise Option::ControlSignal, "called `Option#unwrap!` on an `None` value: #{self}"
  116. end
  117. 2 sig { override.params(message: String).returns(InnerType) }
  118. 1 def expect!(message)
  119. 1 raise Option::ControlSignal, message
  120. end
  121. 2 sig { override.params(block: T.proc.returns(T.untyped)).returns(InnerType) }
  122. 1 def expect_with!(&block)
  123. 1 raise Option::ControlSignal, block.call
  124. end
  125. 2 sig { override.returns(T::Boolean) }
  126. 1 def some? = false
  127. 2 sig { override.returns(T::Boolean) }
  128. 1 def none? = true
  129. 2 sig { override.type_parameters(:NewInnerType).params(_block: T.proc.params(inner: InnerType).returns(Option[T.type_parameter(:NewInnerType)])).returns(Option[T.type_parameter(:NewInnerType)]) }
  130. 1 def map(&_block)
  131. 2 T.cast(self, Option[T.type_parameter(:NewInnerType)])
  132. end
  133. 2 sig { override.params(default: Option[InnerType]).returns(Option[InnerType]) }
  134. 1 def or(default)
  135. 2 default
  136. end
  137. 2 sig { override.type_parameters(:ErrType).params(err: T.type_parameter(:ErrType)).returns(Mangrove::Result[InnerType, T.type_parameter(:ErrType)]) }
  138. 1 def transpose(err)
  139. 1 Result::Err.new(err)
  140. end
  141. end
  142. 2 sig { abstract.params(other: BasicObject).returns(T::Boolean) }
  143. 1 def ==(other); end
  144. 2 sig { abstract.params(default: InnerType).returns(InnerType) }
  145. 1 def unwrap_or(default); end
  146. 2 sig { abstract.returns(InnerType) }
  147. 1 def unwrap!; end
  148. 2 sig { abstract.params(message: String).returns(InnerType) }
  149. 1 def expect!(message); end
  150. 2 sig { abstract.params(block: T.proc.returns(T.untyped)).returns(InnerType) }
  151. 1 def expect_with!(&block); end
  152. 2 sig { abstract.returns(T::Boolean) }
  153. 1 def some?; end
  154. 2 sig { abstract.returns(T::Boolean) }
  155. 1 def none?; end
  156. 2 sig { abstract.type_parameters(:NewInnerType).params(block: T.proc.params(inner: InnerType).returns(Option[T.type_parameter(:NewInnerType)])).returns(::Mangrove::Option[T.type_parameter(:NewInnerType)]) }
  157. 1 def map(&block); end
  158. 2 sig { abstract.params(default: Option[InnerType]).returns(Option[InnerType]) }
  159. 1 def or(default); end
  160. 2 sig { abstract.type_parameters(:ErrType).params(err: T.type_parameter(:ErrType)).returns(Mangrove::Result[InnerType, T.type_parameter(:ErrType)]) }
  161. 1 def transpose(err); end
  162. end
  163. end

lib/mangrove/option/control_signal.rb

94.12% lines covered

50.0% branches covered

17 relevant lines. 16 lines covered and 1 lines missed.
2 total branches, 1 branches covered and 1 branches missed.
    
  1. # typed: strict
  2. # frozen_string_literal: true
  3. 1 require "mangrove/control_flow/control_signal"
  4. 1 module Mangrove
  5. 1 module Option
  6. 1 class ControlSignal < StandardError
  7. 1 extend T::Sig
  8. 1 include Mangrove::ControlFlow::ControlSignal
  9. 2 sig { params(inner_value: T.untyped).void }
  10. 1 def initialize(inner_value)
  11. 5 @inner_value = inner_value
  12. 5 super
  13. end
  14. 2 sig { override.params(other: BasicObject).returns(T::Boolean) }
  15. 1 def ==(other)
  16. 2 case other
  17. when: 2 when ControlSignal
  18. 2 other.inner_value == inner_value
  19. else: 0 else
  20. false
  21. end
  22. end
  23. 2 sig { override.returns(T.untyped) }
  24. 1 attr_reader :inner_value
  25. end
  26. end
  27. end

lib/mangrove/result.rb

98.69% lines covered

73.33% branches covered

305 relevant lines. 301 lines covered and 4 lines missed.
15 total branches, 11 branches covered and 4 branches missed.
    
  1. # typed: strict
  2. # frozen_string_literal: true
  3. 1 require_relative "result/control_signal"
  4. 1 require_relative "result/ext"
  5. 1 module Mangrove
  6. # Result is a type that represents either success (`Ok`) or failure (`Err`).
  7. 1 module Result
  8. 1 extend T::Sig
  9. 1 extend T::Generic
  10. 1 extend T::Helpers
  11. 1 include Kernel
  12. 1 sealed!
  13. 1 interface!
  14. 1 OkType = type_member(:out)
  15. 1 ErrType = type_member(:out)
  16. 2 sig { abstract.params(other: BasicObject).returns(T::Boolean) }
  17. 1 def ==(other); end
  18. # @deprecated Use #is_a?(Result::Ok) instead to enable Sorbet to define types statically.
  19. # This method will be removed in future versions.
  20. 2 sig { abstract.returns(T::Boolean) }
  21. 1 def ok?; end
  22. # @deprecated Use #is_a?(Result::Err) instead to enable Sorbet to define types statically.
  23. 2 sig { abstract.returns(T::Boolean) }
  24. 1 def err?; end
  25. 2 sig { abstract.returns(OkType) }
  26. 1 def unwrap!; end
  27. 2 sig { abstract.params(block: T.proc.params(err: ErrType).returns(Exception)).returns(OkType) }
  28. 1 def unwrap_or_raise_with!(&block); end
  29. 2 sig { abstract.params(exception: Exception).returns(OkType) }
  30. 1 def unwrap_or_raise!(exception); end
  31. 2 sig { abstract.returns(OkType) }
  32. 1 def unwrap_or_raise_inner!; end
  33. 2 sig { abstract.params(ctx: Result::CollectingContext[OkType, ErrType]).returns(OkType) }
  34. 1 def unwrap_in(ctx); end
  35. 2 sig { abstract.params(message: String).returns(OkType) }
  36. 1 def expect!(message); end
  37. 2 sig { abstract.type_parameters(:E).params(block: T.proc.params(err: ErrType).returns(T.type_parameter(:E))).returns(OkType) }
  38. 1 def expect_with!(&block); end
  39. 2 sig { abstract.type_parameters(:NewOkType, :NewErrType).params(block: T.proc.params(this: Result[OkType, ErrType]).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  40. 1 def map(&block); end
  41. 2 sig { abstract.type_parameters(:NewOkType, :NewErrType).params(_t_new_ok: T::Class[T.type_parameter(:NewOkType)], _t_new_err: T::Class[T.type_parameter(:NewErrType)], block: T.proc.params(this: Result[OkType, ErrType]).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  42. 1 def map_wt(_t_new_ok, _t_new_err, &block); end
  43. 2 sig { abstract.type_parameters(:NewOkType).params(block: T.proc.params(this: OkType).returns(T.type_parameter(:NewOkType))).returns(Result[T.type_parameter(:NewOkType), ErrType]) }
  44. 1 def map_ok(&block); end
  45. 2 sig { abstract.type_parameters(:NewOkType).params(_t_new_ok: T::Class[T.type_parameter(:NewOkType)], block: T.proc.params(this: OkType).returns(T.type_parameter(:NewOkType))).returns(Result[T.type_parameter(:NewOkType), ErrType]) }
  46. 1 def map_ok_wt(_t_new_ok, &block); end
  47. 2 sig { abstract.type_parameters(:NewErrType).params(block: T.proc.params(this: ErrType).returns(T.type_parameter(:NewErrType))).returns(Result[OkType, T.type_parameter(:NewErrType)]) }
  48. 1 def map_err(&block); end
  49. 2 sig { abstract.type_parameters(:NewErrType).params(_t_new_err: T::Class[T.type_parameter(:NewErrType)], block: T.proc.params(this: ErrType).returns(T.type_parameter(:NewErrType))).returns(Result[OkType, T.type_parameter(:NewErrType)]) }
  50. 1 def map_err_wt(_t_new_err, &block); end
  51. 2 sig { abstract.params(block: T.proc.params(this: OkType).void).returns(Result[OkType, ErrType]) }
  52. 1 def tap_ok(&block); end
  53. 2 sig { abstract.params(block: T.proc.params(this: ErrType).void).returns(Result[OkType, ErrType]) }
  54. 1 def tap_err(&block); end
  55. 2 sig { abstract.type_parameters(:NewOkType, :NewErrType).params(other: Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]).returns(T.any(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)], Result[T.type_parameter(:NewOkType), ErrType])) }
  56. 1 def and(other); end
  57. 2 sig { abstract.type_parameters(:NewOkType, :NewErrType).params(block: T.proc.params(this: OkType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(T.any(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)], Result[T.type_parameter(:NewOkType), ErrType])) }
  58. 1 def and_then(&block); end
  59. 2 sig { abstract.type_parameters(:NewOkType, :NewErrType).params(_t_new_ok: T::Class[T.type_parameter(:NewOkType)], block: T.proc.params(this: OkType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(T.any(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)], Result[T.type_parameter(:NewOkType), ErrType])) }
  60. 1 def and_then_wt(_t_new_ok, &block); end
  61. 1 sig {
  62. 1 abstract
  63. .type_parameters(:NewErrType)
  64. .params(
  65. new_err_inner: T.type_parameter(:NewErrType),
  66. condition: T.proc.params(inner: OkType).returns(T::Boolean)
  67. )
  68. .returns(
  69. T.any(Result[OkType, T.type_parameter(:NewErrType)], Result[OkType, ErrType])
  70. )
  71. }
  72. 1 def and_err_if(new_err_inner, &condition); end
  73. 2 sig { abstract.type_parameters(:NewOkType, :NewErrType).params(other: Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]).returns(T.any(Result[OkType, T.type_parameter(:NewErrType)], Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])) }
  74. 1 def or(other); end
  75. 2 sig { abstract.type_parameters(:NewOkType, :NewErrType).params(block: T.proc.params(this: ErrType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(T.any(Result[OkType, T.type_parameter(:NewErrType)], Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])) }
  76. 1 def or_else(&block); end
  77. 2 sig { abstract.type_parameters(:NewOkType, :NewErrType).params(_t_new_err: T::Class[T.type_parameter(:NewErrType)], block: T.proc.params(this: ErrType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(T.any(Result[OkType, T.type_parameter(:NewErrType)], Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])) }
  78. 1 def or_else_wt(_t_new_err, &block); end
  79. 1 sig {
  80. 1 abstract
  81. .type_parameters(:NewOkType)
  82. .params(
  83. new_ok_inner: T.type_parameter(:NewOkType),
  84. condition: T.proc.params(inner: ErrType).returns(T::Boolean)
  85. )
  86. .returns(
  87. T.any(Result[T.type_parameter(:NewOkType), ErrType], Result[OkType, ErrType])
  88. )
  89. }
  90. 1 def or_ok_if(new_ok_inner, &condition); end
  91. 1 class << self
  92. 1 extend T::Sig
  93. 1 extend T::Generic
  94. 1 OkType = type_member
  95. 1 ErrType = type_member
  96. 2 sig { type_parameters(:T, :E).params(results: T::Enumerable[Result[T.type_parameter(:T), T.type_parameter(:E)]]).returns(Result[T::Enumerable[T.type_parameter(:T)], T::Enumerable[T.type_parameter(:E)]]) }
  97. 1 def from_results(results)
  98. 4 errs = results.filter(&:err?)
  99. 4 if errs.empty?
  100. then: 2 # This is safe as errs is empty.
  101. 8 Result::Ok[T::Enumerable[T.type_parameter(:T)]].new(results.map { |r| T.cast(r, Result::Ok[T.type_parameter(:T)]).ok_inner })
  102. else
  103. else: 2 # This is safe as errs is results where err? is true
  104. 6 Result::Err[T::Enumerable[T.type_parameter(:E)]].new(errs.map { |r| T.cast(r, Result::Err[T.type_parameter(:E)]).err_inner })
  105. end
  106. end
  107. 2 sig { type_parameters(:OkType).params(inner: T.type_parameter(:OkType)).returns(Result::Ok[T.type_parameter(:OkType)]) }
  108. 1 def ok(inner)
  109. 1 Result::Ok[T.type_parameter(:OkType)].new(inner)
  110. end
  111. # @deprecated
  112. 2 sig { type_parameters(:OkType, :ErrType).params(inner: T.type_parameter(:OkType), _t_err: T::Class[T.type_parameter(:ErrType)]).returns(Result::Ok[T.type_parameter(:OkType)]) }
  113. 1 def ok_wt(inner, _t_err)
  114. 12 Result::Ok[T.type_parameter(:OkType)].new(inner)
  115. end
  116. 2 sig { type_parameters(:ErrType).params(inner: T.type_parameter(:ErrType)).returns(Result::Err[T.type_parameter(:ErrType)]) }
  117. 1 def err(inner)
  118. 1 Result::Err[T.type_parameter(:ErrType)].new(inner)
  119. end
  120. # @deprecated
  121. 2 sig { type_parameters(:OkType, :ErrType).params(_t_ok: T::Class[T.type_parameter(:OkType)], inner: T.type_parameter(:ErrType)).returns(Result::Err[T.type_parameter(:ErrType)]) }
  122. 1 def err_wt(_t_ok, inner)
  123. 9 Result::Err[T.type_parameter(:ErrType)].new(inner)
  124. end
  125. 1 sig {
  126. 1 type_parameters(:O, :E)
  127. .params(
  128. _t_ok: T::Class[T.type_parameter(:O)],
  129. _t_err: T::Class[T.type_parameter(:E)],
  130. block: T.proc.params(
  131. do_block: CollectingContext[T.type_parameter(:O), T.type_parameter(:E)]
  132. ).returns(Mangrove::Result[T.type_parameter(:O), T.type_parameter(:E)])
  133. )
  134. .returns(Mangrove::Result[T.type_parameter(:O), T.type_parameter(:E)])
  135. }
  136. 1 def collecting(_t_ok, _t_err, &block)
  137. 3 catch(:__mangrove_result_collecting_context_return) {
  138. 3 block.call(CollectingContext[T.type_parameter(:O), T.type_parameter(:E)].new)
  139. }
  140. end
  141. end
  142. 1 class CollectingContext
  143. 1 extend T::Sig
  144. 1 extend T::Generic
  145. 1 O = type_member
  146. 1 E = type_member
  147. 2 sig { params(result: Mangrove::Result[O, E]).returns(O) }
  148. 1 def try!(result)
  149. 6 case result
  150. when: 4 when Mangrove::Result::Ok
  151. 4 result.ok_inner
  152. when: 2 when Mangrove::Result::Err
  153. 2 throw :__mangrove_result_collecting_context_return, result
  154. else: 0 else
  155. T.absurd(result)
  156. end
  157. end
  158. end
  159. 1 class Ok
  160. 1 extend T::Sig
  161. 1 extend T::Generic
  162. 1 extend T::Helpers
  163. 1 include Result
  164. 1 OkType = type_member
  165. 1 ErrType = type_member { { fixed: T.noreturn } }
  166. 2 sig { params(inner: OkType).void }
  167. 1 def initialize(inner)
  168. 151 @inner = inner
  169. end
  170. 2 sig { override.params(other: BasicObject).returns(T::Boolean) }
  171. 1 def ==(other)
  172. 49 case other
  173. when: 49 when Result::Ok
  174. 49 other.instance_variable_get(:@inner) == @inner
  175. when: 0 when Result::Err
  176. false
  177. else # rubocop:disable Lint/DuplicateBranch
  178. else: 0 # Because == is defined on BasicObject, we can't be sure that `other` is an Option
  179. false
  180. end
  181. end
  182. 2 sig { returns(OkType) }
  183. 1 def ok_inner
  184. 13 @inner
  185. end
  186. 2 sig { override.returns(OkType) }
  187. 1 def unwrap!
  188. 6 @inner
  189. end
  190. 2 sig { override.params(_exception: Exception).returns(OkType) }
  191. 1 def unwrap_or_raise!(_exception)
  192. 2 @inner
  193. end
  194. 2 sig { override.params(_block: T.proc.params(err: ErrType).returns(Exception)).returns(OkType) }
  195. 1 def unwrap_or_raise_with!(&_block)
  196. 2 @inner
  197. end
  198. 2 sig { override.returns(OkType) }
  199. 1 def unwrap_or_raise_inner!
  200. 2 @inner
  201. end
  202. 2 sig { override.params(_ctx: Result::CollectingContext[OkType, ErrType]).returns(OkType) }
  203. 1 def unwrap_in(_ctx)
  204. 3 @inner
  205. end
  206. 2 sig { override.params(_message: String).returns(OkType) }
  207. 1 def expect!(_message)
  208. 2 @inner
  209. end
  210. 2 sig { override.type_parameters(:E).params(_block: T.proc.params(err: ErrType).returns(T.type_parameter(:E))).returns(OkType) }
  211. 1 def expect_with!(&_block)
  212. 2 @inner
  213. end
  214. # @deprecated Use #is_a?(Result::Ok) instead to enable Sorbet to define types statically.
  215. 2 sig { override.returns(T::Boolean) }
  216. 1 def ok? = true
  217. # @deprecated Use #is_a?(Result::Err) instead to enable Sorbet to define types statically.
  218. 2 sig { override.returns(T::Boolean) }
  219. 1 def err? = false
  220. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(block: T.proc.params(this: Result[OkType, ErrType]).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  221. 1 def map(&block)
  222. 2 block.call(self)
  223. end
  224. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(_t_new_ok: T::Class[T.type_parameter(:NewOkType)], _t_new_err: T::Class[T.type_parameter(:NewErrType)], block: T.proc.params(this: Result[OkType, ErrType]).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  225. 1 def map_wt(_t_new_ok, _t_new_err, &block)
  226. 2 block.call(self)
  227. end
  228. 2 sig { override.type_parameters(:NewOkType).params(block: T.proc.params(this: OkType).returns(T.type_parameter(:NewOkType))).returns(Result[T.type_parameter(:NewOkType), ErrType]) }
  229. 1 def map_ok(&block)
  230. 4 Result::Ok[T.type_parameter(:NewOkType)].new(block.call(@inner))
  231. end
  232. # Because sorbet does not deduct types from return values well. This method takes a type of new inner values.
  233. 2 sig { override.type_parameters(:NewOkType).params(_t_new_ok: T::Class[T.type_parameter(:NewOkType)], block: T.proc.params(this: OkType).returns(T.type_parameter(:NewOkType))).returns(Result[T.type_parameter(:NewOkType), ErrType]) }
  234. 1 def map_ok_wt(_t_new_ok, &block)
  235. 2 Result::Ok[T.type_parameter(:NewOkType)].new(block.call(@inner))
  236. end
  237. 2 sig { override.type_parameters(:NewErrType).params(_block: T.proc.params(this: ErrType).returns(T.type_parameter(:NewErrType))).returns(Result[OkType, T.type_parameter(:NewErrType)]) }
  238. 1 def map_err(&_block)
  239. 2 self
  240. end
  241. # Because sorbet does not deduct types from return values well. This method takes a type of new inner values.
  242. 2 sig { override.type_parameters(:NewErrType).params(_t_new_err: T::Class[T.type_parameter(:NewErrType)], _block: T.proc.params(this: ErrType).returns(T.type_parameter(:NewErrType))).returns(Result[OkType, T.type_parameter(:NewErrType)]) }
  243. 1 def map_err_wt(_t_new_err, &_block)
  244. 7 self
  245. end
  246. 2 sig { override.params(block: T.proc.params(this: OkType).void).returns(Result[OkType, ErrType]) }
  247. 1 def tap_ok(&block)
  248. 2 block.call(@inner)
  249. 2 self
  250. end
  251. 2 sig { override.params(_block: T.proc.params(this: ErrType).void).returns(Result[OkType, ErrType]) }
  252. 1 def tap_err(&_block)
  253. 2 self
  254. end
  255. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(other: Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  256. 1 def and(other)
  257. 2 other
  258. end
  259. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(block: T.proc.params(this: OkType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  260. 1 def and_then(&block)
  261. 2 block.call(@inner)
  262. end
  263. # @deprecated
  264. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(_t_new_ok: T::Class[T.type_parameter(:NewOkType)], block: T.proc.params(this: OkType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  265. 1 def and_then_wt(_t_new_ok, &block)
  266. 8 block.call(@inner)
  267. end
  268. 1 sig {
  269. 1 override
  270. .type_parameters(:NewErrType)
  271. .params(
  272. new_err_inner: T.type_parameter(:NewErrType),
  273. condition: T.proc.params(inner: OkType).returns(T::Boolean)
  274. )
  275. .returns(
  276. Result[OkType, T.type_parameter(:NewErrType)]
  277. )
  278. }
  279. 1 def and_err_if(new_err_inner, &condition)
  280. 4 then: 2 if condition.call(@inner)
  281. 2 Result::Err[T.type_parameter(:NewErrType)].new(new_err_inner)
  282. else: 2 else
  283. 2 self
  284. end
  285. end
  286. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(_other: Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]).returns(Result[OkType, T.type_parameter(:NewErrType)]) }
  287. 1 def or(_other)
  288. 2 self
  289. end
  290. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(_block: T.proc.params(this: ErrType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[OkType, T.type_parameter(:NewErrType)]) }
  291. 1 def or_else(&_block)
  292. 2 self
  293. end
  294. # @deprecated
  295. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(_t_new_err: T::Class[T.type_parameter(:NewErrType)], _block: T.proc.params(this: ErrType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[OkType, T.type_parameter(:NewErrType)]) }
  296. 1 def or_else_wt(_t_new_err, &_block)
  297. 2 self
  298. end
  299. 1 sig {
  300. 1 override
  301. .type_parameters(:NewOkType)
  302. .params(
  303. _new_ok_inner: T.type_parameter(:NewOkType),
  304. _condition: T.proc.params(inner: ErrType).returns(T::Boolean)
  305. )
  306. .returns(
  307. Result[OkType, ErrType]
  308. )
  309. }
  310. 1 def or_ok_if(_new_ok_inner, &_condition)
  311. 4 self
  312. end
  313. 2 sig { returns(String) }
  314. 1 def to_s
  315. 1 "#{super}: inner=`#{@inner}`"
  316. end
  317. end
  318. 1 class Err
  319. 1 extend T::Sig
  320. 1 extend T::Generic
  321. 1 extend T::Helpers
  322. 1 include Result
  323. 1 OkType = type_member { { fixed: T.noreturn } }
  324. 1 ErrType = type_member
  325. 2 sig { params(inner: ErrType).void }
  326. 1 def initialize(inner)
  327. 126 @inner = inner
  328. end
  329. 2 sig { override.params(other: BasicObject).returns(T::Boolean) }
  330. 1 def ==(other)
  331. 51 case other
  332. when: 0 when Result::Ok
  333. false
  334. when: 49 when Result::Err
  335. 49 other.instance_variable_get(:@inner) == @inner
  336. else # rubocop:disable Lint/DuplicateBranch
  337. else: 2 # Because == is defined on BasicObject, we can't be sure that `other` is an Option
  338. 2 false
  339. end
  340. end
  341. 2 sig { returns(ErrType) }
  342. 1 def err_inner
  343. 9 @inner
  344. end
  345. 2 sig { override.returns(OkType) }
  346. 1 def unwrap!
  347. 2 raise Result::ControlSignal, @inner
  348. end
  349. 2 sig { override.params(exception: Exception).returns(OkType) }
  350. 1 def unwrap_or_raise!(exception)
  351. 1 raise exception
  352. end
  353. 2 sig { override.params(block: T.proc.params(err: ErrType).returns(Exception)).returns(OkType) }
  354. 1 def unwrap_or_raise_with!(&block)
  355. 1 raise block.call(@inner)
  356. end
  357. 2 sig { override.returns(OkType) }
  358. 1 def unwrap_or_raise_inner!
  359. 1 raise T.unsafe(@inner)
  360. end
  361. 2 sig { override.params(_ctx: Result::CollectingContext[OkType, ErrType]).returns(T.noreturn) }
  362. 1 def unwrap_in(_ctx)
  363. 2 throw :__mangrove_result_collecting_context_return, self
  364. end
  365. 2 sig { override.params(message: String).returns(OkType) }
  366. 1 def expect!(message)
  367. 1 raise Result::ControlSignal, message
  368. end
  369. 2 sig { override.type_parameters(:E).params(block: T.proc.params(err: ErrType).returns(T.type_parameter(:E))).returns(OkType) }
  370. 1 def expect_with!(&block)
  371. 1 raise Result::ControlSignal, block.call(@inner)
  372. end
  373. # @deprecated Use #is_a?(Result::Ok) instead to enable Sorbet to define types statically.
  374. 2 sig { override.returns(T::Boolean) }
  375. 1 def ok? = false
  376. # @deprecated Use #is_a?(Result::Err) instead to enable Sorbet to define types statically.
  377. 2 sig { override.returns(T::Boolean) }
  378. 1 def err? = true
  379. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(block: T.proc.params(this: Result[OkType, ErrType]).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  380. 1 def map(&block)
  381. 2 block.call(self)
  382. end
  383. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(_t_new_ok: T::Class[T.type_parameter(:NewOkType)], _t_new_err: T::Class[T.type_parameter(:NewErrType)], block: T.proc.params(this: Result[OkType, ErrType]).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  384. 1 def map_wt(_t_new_ok, _t_new_err, &block)
  385. 2 block.call(self)
  386. end
  387. 2 sig { override.type_parameters(:NewOkType).params(_block: T.proc.params(this: OkType).returns(T.type_parameter(:NewOkType))).returns(Result[T.type_parameter(:NewOkType), ErrType]) }
  388. 1 def map_ok(&_block)
  389. 4 self
  390. end
  391. 2 sig { override.type_parameters(:NewOkType).params(_t_new_ok: T::Class[T.type_parameter(:NewOkType)], _block: T.proc.params(this: OkType).returns(T.type_parameter(:NewOkType))).returns(Result[T.type_parameter(:NewOkType), ErrType]) }
  392. 1 def map_ok_wt(_t_new_ok, &_block)
  393. 2 self
  394. end
  395. 2 sig { override.type_parameters(:NewErrType).params(block: T.proc.params(this: ErrType).returns(T.type_parameter(:NewErrType))).returns(Result[OkType, T.type_parameter(:NewErrType)]) }
  396. 1 def map_err(&block)
  397. 2 Result::Err[T.type_parameter(:NewErrType)].new(block.call(@inner))
  398. end
  399. 2 sig { override.type_parameters(:NewErrType).params(_t_new_err: T::Class[T.type_parameter(:NewErrType)], block: T.proc.params(this: ErrType).returns(T.type_parameter(:NewErrType))).returns(Result[OkType, T.type_parameter(:NewErrType)]) }
  400. 1 def map_err_wt(_t_new_err, &block)
  401. 4 Result::Err[T.type_parameter(:NewErrType)].new(block.call(@inner))
  402. end
  403. 2 sig { override.params(_block: T.proc.params(this: OkType).void).returns(Result[OkType, ErrType]) }
  404. 1 def tap_ok(&_block)
  405. 2 self
  406. end
  407. 2 sig { override.params(block: T.proc.params(this: ErrType).void).returns(Result[OkType, ErrType]) }
  408. 1 def tap_err(&block)
  409. 2 block.call(@inner)
  410. 2 self
  411. end
  412. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(_other: Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]).returns(Result[T.type_parameter(:NewOkType), ErrType]) }
  413. 1 def and(_other)
  414. 1 self
  415. end
  416. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(_block: T.proc.params(this: OkType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), ErrType]) }
  417. 1 def and_then(&_block)
  418. 2 self
  419. end
  420. # @deprecated
  421. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(_t_new_ok: T::Class[T.type_parameter(:NewOkType)], _block: T.proc.params(this: OkType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), ErrType]) }
  422. 1 def and_then_wt(_t_new_ok, &_block)
  423. 3 self
  424. end
  425. 1 sig {
  426. 1 override
  427. .type_parameters(:NewErrType)
  428. .params(
  429. _new_err_inner: T.type_parameter(:NewErrType),
  430. _condition: T.proc.params(inner: OkType).returns(T::Boolean)
  431. )
  432. .returns(
  433. Result[OkType, ErrType]
  434. )
  435. }
  436. 1 def and_err_if(_new_err_inner, &_condition)
  437. 4 self
  438. end
  439. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(other: Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  440. 1 def or(other)
  441. 2 other
  442. end
  443. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(block: T.proc.params(this: ErrType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  444. 1 def or_else(&block)
  445. 2 block.call(@inner)
  446. end
  447. 2 sig { override.type_parameters(:NewOkType, :NewErrType).params(_t_new_err: T::Class[T.type_parameter(:NewErrType)], block: T.proc.params(this: ErrType).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)])).returns(Result[T.type_parameter(:NewOkType), T.type_parameter(:NewErrType)]) }
  448. 1 def or_else_wt(_t_new_err, &block)
  449. 2 block.call(@inner)
  450. end
  451. 1 sig {
  452. 1 override
  453. .type_parameters(:NewOkType)
  454. .params(
  455. new_ok_inner: T.type_parameter(:NewOkType),
  456. condition: T.proc.params(inner: ErrType).returns(T::Boolean)
  457. )
  458. .returns(
  459. Result[T.type_parameter(:NewOkType), ErrType]
  460. )
  461. }
  462. 1 def or_ok_if(new_ok_inner, &condition)
  463. 4 then: 2 if condition.call(@inner)
  464. 2 Result::Ok[T.type_parameter(:NewOkType)].new(new_ok_inner)
  465. else: 2 else
  466. 2 self
  467. end
  468. end
  469. 2 sig { returns(String) }
  470. 1 def to_s
  471. 1 "#{super}: inner=`#{@inner}`"
  472. end
  473. end
  474. end
  475. end

lib/mangrove/result/control_signal.rb

94.12% lines covered

50.0% branches covered

17 relevant lines. 16 lines covered and 1 lines missed.
2 total branches, 1 branches covered and 1 branches missed.
    
  1. # typed: strict
  2. # frozen_string_literal: true
  3. 1 require "mangrove/control_flow/control_signal"
  4. 1 module Mangrove
  5. 1 module Result
  6. 1 class ControlSignal < StandardError
  7. 1 extend T::Sig
  8. 1 include Mangrove::ControlFlow::ControlSignal
  9. 2 sig { params(inner_value: T.untyped).void }
  10. 1 def initialize(inner_value)
  11. 6 @inner_value = inner_value
  12. 6 super
  13. end
  14. 2 sig { override.params(other: BasicObject).returns(T::Boolean) }
  15. 1 def ==(other)
  16. 2 case other
  17. when: 2 when ControlSignal
  18. 2 other.inner_value == inner_value
  19. else: 0 else
  20. false
  21. end
  22. end
  23. 2 sig { override.returns(T.untyped) }
  24. 1 attr_reader :inner_value
  25. end
  26. end
  27. end

lib/mangrove/result/ext.rb

100.0% lines covered

100.0% branches covered

8 relevant lines. 8 lines covered and 0 lines missed.
0 total branches, 0 branches covered and 0 branches missed.
    
  1. # typed: true
  2. # frozen_string_literal: true
  3. 1 module Mangrove
  4. 1 module Result
  5. 1 module Ext
  6. 1 extend T::Sig
  7. 1 def in_ok
  8. 5 Mangrove::Result::Ok.new(self)
  9. end
  10. 1 def in_err
  11. 5 Mangrove::Result::Err.new(self)
  12. end
  13. end
  14. end
  15. end

lib/tapioca/dsl/compilers/mangrove_enum.rb

80.85% lines covered

40.0% branches covered

47 relevant lines. 38 lines covered and 9 lines missed.
10 total branches, 4 branches covered and 6 branches missed.
    
  1. # typed: strict
  2. # frozen_string_literal: true
  3. 1 require "mangrove"
  4. 1 require "tapioca/dsl"
  5. # @api private
  6. 1 module Tapioca
  7. 1 module Compilers
  8. 1 class MangroveEnum < Tapioca::Dsl::Compiler
  9. 1 extend T::Sig
  10. 1 ConstantType = type_member { { fixed: T.class_of(::Mangrove::Enum) } }
  11. 2 sig { override.returns(T::Enumerable[Module]) }
  12. 1 def self.gather_constants
  13. 2742 all_classes.select { |c| c.singleton_class < ::Mangrove::Enum && T::AbstractUtils.abstract_module?(c) }
  14. end
  15. 2 sig { override.void }
  16. 1 def decorate
  17. 1 root.create_path(constant) { |constant_type|
  18. 1 constant_type.nodes.append(
  19. RBI::Helper.new("abstract"),
  20. RBI::Helper.new("sealed")
  21. )
  22. 1 variants = constant
  23. .constants
  24. .filter_map { |variant_name|
  25. 1 maybe_variant = constant.const_get(variant_name, false)
  26. 1 then: 1 else: 0 if maybe_variant.instance_variable_defined?(:@__mangrove__enum_inner_type)
  27. 1 maybe_variant
  28. end
  29. }
  30. 1 .sort_by { |variant| variant.name.to_s }
  31. 1 inner_types = variants.map { |variant|
  32. 1 inner_type = runtime_type_to_type_name(variant.instance_variable_get(:@__mangrove__enum_inner_type))
  33. 1 constant_type.create_class(variant.name.gsub(/.*::/, ""), superclass_name: constant_type.fully_qualified_name) { |variant_type|
  34. 1 variant_type.create_method("initialize", parameters: [create_param("inner", type: inner_type)], return_type: "void")
  35. 1 variant_type.create_method("inner", return_type: inner_type)
  36. 1 variant_type.create_method("as_super", return_type: constant.name.to_s)
  37. 1 variant_type.sort_nodes!
  38. }
  39. 1 inner_type
  40. }
  41. 1 then: 1 return_type = if inner_types.size == 1
  42. 1 T.must(inner_types.first)
  43. else: 0 else
  44. "T.any(#{inner_types.join(", ")})"
  45. end
  46. 1 constant_type.create_method("inner", return_type:)
  47. 1 constant_type.create_method("as_super", return_type: constant.name.to_s)
  48. 1 constant_type.sort_nodes!
  49. }
  50. end
  51. 1 private
  52. 2 sig { params(runtime_type: T.untyped).returns(String) }
  53. 1 def runtime_type_to_type_name(runtime_type)
  54. 1 then: 0 if runtime_type.is_a?(Array)
  55. content = runtime_type.map { |inner|
  56. runtime_type_to_type_name(inner)
  57. }.join(", ")
  58. else: 1 "[#{content}]"
  59. 1 then: 0 elsif runtime_type.is_a?(Hash)
  60. content = runtime_type.map { |k, v|
  61. else: 0 then: 0 unless k.is_a?(Symbol) || k.is_a?(String)
  62. raise "shape key must be Symbol or String"
  63. end
  64. "#{k}: #{runtime_type_to_type_name(v)}"
  65. }.join(", ")
  66. "{ #{content} }"
  67. else: 1 else
  68. 1 runtime_type.to_s
  69. end
  70. end
  71. end
  72. end
  73. end

lib/tapioca/dsl/compilers/mangrove_result_ext.rb

100.0% lines covered

50.0% branches covered

21 relevant lines. 21 lines covered and 0 lines missed.
2 total branches, 1 branches covered and 1 branches missed.
    
  1. # typed: strict
  2. # frozen_string_literal: true
  3. 1 require "mangrove/result/ext"
  4. 1 require "tapioca/dsl"
  5. 1 require "sorbet-runtime"
  6. 1 module Tapioca
  7. 1 module Compilers
  8. 1 class MangroveResultExt < Tapioca::Dsl::Compiler
  9. 1 extend T::Sig
  10. 1 ConstantType = type_member { { fixed: T.class_of(Mangrove::Result::Ext) } }
  11. 2 sig { override.returns(T::Enumerable[Module]) }
  12. 1 def self.gather_constants
  13. 4713 all_classes.select { |c| c < ::Mangrove::Result::Ext }
  14. end
  15. 2 sig { override.void }
  16. 1 def decorate
  17. 2 else: 2 then: 0 return unless valid_constant_name?(constant.to_s)
  18. 2 root.create_path(constant) do |klass|
  19. 2 klass.create_method("in_ok", return_type: "Mangrove::Result::Ok[#{constant}]")
  20. 2 klass.create_method("in_err", return_type: "Mangrove::Result::Err[#{constant}]")
  21. end
  22. rescue NameError
  23. # 握りつぶす
  24. end
  25. 1 private
  26. 2 sig { params(string: String).returns(T::Boolean) }
  27. 1 def valid_constant_name?(string)
  28. 2 Object.const_defined?(string) && !!(string =~ /\A[A-Z][a-zA-Z0-9_]*\z/)
  29. end
  30. end
  31. end
  32. end