Skip to content

Commit

Permalink
Deferred type
Browse files Browse the repository at this point in the history
  • Loading branch information
joeldrapper committed Nov 29, 2024
1 parent 8272890 commit f96dcd9
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/literal.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ def self.check(actual:, expected:)
end

def self.subtype?(type, of:)
type = type.block.call if Types::DeferredType === type

(of == type) || case of
when Literal::Type
of >= type
Expand Down
23 changes: 23 additions & 0 deletions lib/literal/deferred_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

class Literal::Types::DeferredType
include Literal::Type

def initialize(&block)
@block = block
end

attr_reader :block

def inspect
"_Deferred"
end

def ===(other)
@block.call === other
end

def >=(other)
Literal.subtype?(other, of: @block.call)
end
end
5 changes: 5 additions & 0 deletions lib/literal/types.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Literal::Types
autoload :BooleanType, "literal/types/boolean_type"
autoload :ClassType, "literal/types/class_type"
autoload :ConstraintType, "literal/types/constraint_type"
autoload :DeferredType, "literal/deferred_type"
autoload :DescendantType, "literal/types/descendant_type"
autoload :EnumerableType, "literal/types/enumerable_type"
autoload :FalsyType, "literal/types/falsy_type"
Expand Down Expand Up @@ -102,6 +103,10 @@ def _Constraint?(...)
)
end

def _Deferred(...)
DeferredType.new(...)
end

# Matches if the value is a descendant of the given class.
def _Descendant(...)
DescendantType.new(...)
Expand Down
32 changes: 32 additions & 0 deletions test/types.test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,38 @@ def expect_type_error(expected:, actual:, message:)
end
end

test "_Deferred" do
recursive = _Hash(
String,
_Deferred { recursive }
)

assert recursive === {
"a" => {
"b" => {
"c" => {
"d" => {
"e" => {
"f" => {
"g" => {},
},
},
},
},
},
},
}

refute recursive === {
"a" => {
"b" => { 1 => {} },
},
}

assert _Deferred { Numeric } >= Integer
assert _Deferred { Numeric } >= _Deferred { Integer }
end

test "_Any" do
Fixtures::Objects.each do |object|
assert _Any === object
Expand Down

0 comments on commit f96dcd9

Please sign in to comment.