Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ group :docs do
gem "yard-junk"
end

group :sig do
gem "rbs"
gem "rbs-inline"
end

group :test do
gem "debug_inspector"
gem "dry-types"
Expand Down
42 changes: 42 additions & 0 deletions bin/gen-sig
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require "fileutils"
require "pathname"

root_path = Pathname.new(File.expand_path("../", __dir__))

manifest_path = root_path.join("sig/manifest.yaml")
manifest = manifest_path.exist? ? manifest_path.read : "dependencies: []"

FileUtils.rm_rf(root_path.join("sig"))

system "rbs-inline lib --opt-out --output=./sig"

EMPTY_COMMENT_BEFORE_CODE = /
^[ \t]*\#[ \t]*\n
(?=^[ \t]*[^#\s])
/mx
EMPTY_STRING = ""
GENERATED_LINE = /^ *# Generated from .+.rb with RBS::Inline *$/
RBS_COMMENT_BLOCK = /
^[ \t]*\#[ \t]*@rbs.*\n
(?:^[ \t]*\#.*\n)*
/x

root_path.glob("sig/**/*.rbs").each do |file|
contents = file.read

contents.gsub!(GENERATED_LINE, EMPTY_STRING)
&.gsub!(RBS_COMMENT_BLOCK, EMPTY_STRING)
&.gsub!(EMPTY_COMMENT_BEFORE_CODE, EMPTY_STRING)
&.strip

if contents.nil? || contents.strip.empty?
File.delete(file)
else
File.write(file, "#{contents}\n")
end
end

File.write(manifest_path, manifest)
3 changes: 3 additions & 0 deletions lib/dry/monads.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Dry
# @api public
module Monads
# @api private
# @rbs () -> Zietwerk::Loader
def self.loader
@loader ||= ::Zeitwerk::Loader.new.tap do |loader|
root = ::File.expand_path("..", __dir__)
Expand All @@ -31,6 +32,7 @@ def self.loader
end

# @private
# @rbs (Class | Module base) -> void
def self.included(base)
if all_loaded?
base.include(*constructors)
Expand Down Expand Up @@ -68,6 +70,7 @@ def self.included(base)
# @param [Array<Symbol>] monads
# @return [Module]
# @api public
# @rbs (*Symbol monads) -> Module
def self.[](*monads)
monads.sort!
@mixins.fetch_or_store(monads.hash) do
Expand Down
4 changes: 4 additions & 0 deletions lib/dry/monads/conversion_stubs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
module Dry
module Monads
module ConversionStubs
# @rbs (*Symbol method_names) -> void
def self.[](*method_names)
::Module.new do
method_names.each do |name|
Expand All @@ -16,14 +17,17 @@ def self.[](*method_names)
module Methods
module_function

# @rbs () -> Maybe
def to_maybe
raise "Load Maybe first with require 'dry/monads/maybe'"
end

# @rbs () -> Result
def to_result
raise "Load Result first with require 'dry/monads/result'"
end

# @rbs () -> Validated
def to_validated
raise "Load Validated first with require 'dry/monads/validated'"
end
Expand Down
2 changes: 2 additions & 0 deletions lib/dry/monads/do.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class << self
#
# @param [Array<Symbol>] methods
# @return [Module]
# @rbs (*Symbol methods) -> Module
def for(*methods)
::Module.new do
singleton_class.define_method(:included) do |base|
Expand All @@ -113,6 +114,7 @@ def for(*methods)
end

# @api private
# @rbs (Class | Module base) -> void
def included(base)
super

Expand Down
8 changes: 7 additions & 1 deletion lib/dry/monads/do/all.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ module Do
module All
# @private
class MethodTracker < ::Module
attr_reader :wrappers
attr_reader :wrappers #: Hash[Class | Module, Module]

# @rbs (Hash[Class | Module, Module] wrappers) -> void
def initialize(wrappers)
super()

Expand Down Expand Up @@ -86,11 +87,13 @@ def included(base)
end
end

# @rbs (Class | Module target) -> void
def extend_object(target)
super
target.prepend(wrappers[target])
end

# @rbs (Class | Module target, Symbol method) -> void
def wrap_method(target, method)
visibility = Do.method_visibility(target, method)
Do.wrap_method(wrappers[target], method, visibility)
Expand All @@ -99,6 +102,7 @@ def wrap_method(target, method)

class << self
# @api private
# @rbs (Class | Module base) -> void
def included(base)
super

Expand All @@ -110,6 +114,7 @@ def included(base)
end

# @api private
# @rbs (Class klass, __todo__ target) -> void
def wrap_defined_methods(klass, target)
klass.public_instance_methods(false).each do |m|
Do.wrap_method(target, m, :public)
Expand All @@ -128,6 +133,7 @@ def wrap_defined_methods(klass, target)
# @api private
module InstanceMixin
# @api private
# @rbs (Class | Module object) -> void
def extended(object)
super

Expand Down
5 changes: 5 additions & 0 deletions lib/dry/monads/lazy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,29 @@ def new(promise = nil, &)
# Forces the compution and returns its value.
#
# @return [Object]
# @rbs () -> Object
def value! = @promise.execute.value!
alias_method :force!, :value!

# Forces the computation. Note that if the computation
# thrown an error it won't be re-raised as opposed to value!/force!.
#
# @return [Lazy]
# @rbs () -> Lazy
def force
@promise.execute
self
end

# @return [Boolean]
# @rbs () -> bool
def evaluated? = @promise.complete?
deprecate :complete?, :evaluated?

undef_method :wait

# @return [String]
# @rbs () -> String
def to_s
state =
case promise.state
Expand Down Expand Up @@ -76,6 +80,7 @@ module Constructors
#
# @param block [Proc]
# @return [Lazy]
# @rbs () {(?) -> __todo__ } -> Lazy
def Lazy(&) = Lazy.new(&)
end

Expand Down
12 changes: 12 additions & 0 deletions lib/dry/monads/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ class << self
#
# @param values [Array<Object>] List elements
# @return [List]
# @rbs (*Object values) -> List
def [](*values) = new(values)

# Coerces a value to a list. `nil` will be coerced to an empty list.
#
# @param value [Object] Value
# @param type [Monad] Embedded monad type (used in case of list of monadic values)
# @return [List]
# @rbs (Object value, Monad type) -> List
def coerce(value, type = nil)
if value.nil?
List.new([], type)
Expand All @@ -36,6 +38,7 @@ def coerce(value, type = nil)
#
# @param value [Object] any object
# @return [List]
# @rbs (?Object value, ?__todo__ type) ?{(?) -> __todo__ } -> List
def pure(value = Undefined, type = nil, &block)
if value.equal?(Undefined)
new([block])
Expand All @@ -53,6 +56,7 @@ def pure(value = Undefined, type = nil, &block)
# @param state [Object.new] Initial state
# @param type [#pure] Type of list element
# @return [List]
# @rbs (Object state, ?__todo__ type) -> List
def unfold(state, type = nil)
xs = []

Expand Down Expand Up @@ -96,6 +100,7 @@ def initialize(value, type = nil)
#
# @param args [Array<Object>] arguments will be passed to the block or proc
# @return [List]
# @rbs(*Object args) ? { (?) -> __todo__ } -> List
def bind(*args)
if block_given?
List.coerce(value.map { yield(_1, *args) }.reduce([], &:+))
Expand All @@ -114,6 +119,7 @@ def bind(*args)
#
# @param args [Array<Object>] arguments will be passed to the block or proc
# @return [List]
# @rbs(*Object args) ? { (?) -> __todo__ } -> List
def fmap(*args)
if block_given?
List.new(value.map { yield(_1, *args) })
Expand All @@ -127,6 +133,7 @@ def fmap(*args)
# If called without a block, this method returns an enumerator, not a List
#
# @return [List,Enumerator]
# @rbs () ?{(?) -> __todo__ } -> (List | Enumerator[Object])
def map(&block)
if block_given?
fmap(block)
Expand All @@ -142,6 +149,7 @@ def map(&block)
#
# @param other [List] Other list
# @return [List]
# @rbs (List other) -> List
def +(other) = List.new(to_ary + other.to_ary)

# Returns a string representation of the list.
Expand All @@ -150,6 +158,7 @@ def +(other) = List.new(to_ary + other.to_ary)
# Dry::Monads::List[1, 2, 3].inspect # => "List[1, 2, 3]"
#
# @return [String]
# @rbs () -> String
def inspect
type_ann = typed? ? "<#{type.name.split("::").last}>" : ""
"List#{type_ann}#{value.inspect}"
Expand All @@ -163,17 +172,20 @@ def inspect
# Returns the first element.
#
# @return [Object]
# @rbs () -> Object
def first = value.first

# Returns the last element.
#
# @return [Object]
# @rbs () -> Object
def last = value.last

# Folds the list from the left.
#
# @param initial [Object] Initial value
# @return [Object]
# @rbs (Object) {(?) -> __todo__ } -> Object
def fold_left(initial, &) = value.reduce(initial, &)
alias_method :foldl, :fold_left
alias_method :reduce, :fold_left
Expand Down
46 changes: 46 additions & 0 deletions sig/dry/monads.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@


module Dry
# Common, idiomatic monads for Ruby
#
# @api public
module Monads
# @api private
def self.loader: () -> Zietwerk::Loader

# @private
def self.included: (Class | Module base) -> void

# Build a module with cherry-picked monads.
# It saves a bit of typing when you add multiple
# monads to one class. Not loaded monads get loaded automatically.
#
# @example
# require 'dry/monads'
#
# class CreateUser
# include Dry::Monads[:result, :do]
#
# def initialize(repo, send_email)
# @repo = repo
# @send_email = send_email
# end
#
# def call(name)
# if @repo.user_exist?(name)
# Failure(:user_exists)
# else
# user = yield @repo.add_user(name)
# yield @send_email.(user)
# Success(user)
# end
# end
# end
#
# @param [Array<Symbol>] monads
# @return [Module]
# @api public
def self.[]: (*Symbol monads) -> Module
end
end

7 changes: 7 additions & 0 deletions sig/dry/monads/all.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@


module Dry
module Monads
end
end

8 changes: 8 additions & 0 deletions sig/dry/monads/constants.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@


module Dry
module Monads
include Core::Constants
end
end

18 changes: 18 additions & 0 deletions sig/dry/monads/conversion_stubs.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@


module Dry
module Monads
module ConversionStubs
def self.[]: (*Symbol method_names) -> void

module Methods
def self?.to_maybe: () -> Maybe

def self?.to_result: () -> Result

def self?.to_validated: () -> Validated
end
end
end
end

12 changes: 12 additions & 0 deletions sig/dry/monads/curry.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@


module Dry
module Monads
# @private
module Curry
# @private
def self.call: (untyped value) -> untyped
end
end
end

Loading
Loading