Skip to content

Commit

Permalink
Final type comparisons
Browse files Browse the repository at this point in the history
  • Loading branch information
joeldrapper committed Nov 28, 2024
1 parent e5285ac commit e6d5e01
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
21 changes: 18 additions & 3 deletions lib/literal/types/truthy_type.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
# frozen_string_literal: true

# @api private
module Literal::Types::TruthyType
def self.inspect = "_Truthy"
class Literal::Types::TruthyTypeClass
include Literal::Type

def self.===(value)
def inspect
"_Truthy"
end

def ===(value)
!!value
end

def >=(other)
case other
when Literal::Types::TruthyType, true
true
else
false
end
end

freeze
end

Literal::Types::TruthyType = Literal::Types::TruthyTypeClass.new.freeze
19 changes: 18 additions & 1 deletion lib/literal/types/tuple_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

# @api private
class Literal::Types::TupleType
include Literal::Type

def initialize(*types)
raise Literal::ArgumentError.new("_Tuple type must have at least one type.") if types.size < 1

@types = types
end

def inspect = "_Tuple(#{@types.map(&:inspect).join(', ')})"
attr_reader :types

def inspect
"_Tuple(#{@types.map(&:inspect).join(', ')})"
end

def ===(value)
return false unless Array === value
Expand Down Expand Up @@ -39,4 +45,15 @@ def record_literal_type_errors(context)
i += 1
end
end

def >=(other)
case other
when Literal::Types::TupleType
@types == other.types
else
false
end
end

freeze
end
23 changes: 19 additions & 4 deletions lib/literal/types/union_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ def initialize(*types)
@types.freeze
end

def inspect = "_Union(#{@types.inspect})"
attr_reader :types

def inspect
"_Union(#{@types.inspect})"
end

def ===(value)
types = @types
Expand Down Expand Up @@ -46,9 +50,20 @@ def record_literal_type_errors(ctx)
ctx.children.clear if ctx.children.none? { |c| c.children.any? }
end

protected

attr_reader :types
def >=(other)
case other
when Literal::Types::UnionType
other.types.all? do |other_type|
@types.any? do |type|
Literal.subtype?(type, of: other_type)
end
end
else
@types.any? do |type|
Literal.subtype?(other, of: type)
end
end
end

private

Expand Down
10 changes: 10 additions & 0 deletions test/types.test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,10 @@ def expect_type_error(expected:, actual:, message:)
refute _Tuple(String, Integer) === ["a"]
refute _Tuple(String, Integer) === nil

assert _Tuple(String, Integer) >= _Tuple(String, Integer)
refute _Tuple(String, Integer) >= _Tuple(String, Float)
refute _Tuple(String, Integer) >= [String, Float]

expect_type_error(expected: _Tuple(String, Integer), actual: [1, "a"], message: <<~ERROR)
Type mismatch
Expand Down Expand Up @@ -630,6 +634,12 @@ def expect_type_error(expected:, actual:, message:)
refute type === []
refute type === nil

assert _Union(String, Integer) >= _Union(String, Integer)
refute _Union(String, Integer) >= _Union(String, Float)
assert _Union(String, Integer) >= String
refute _Union(String, Integer) >= Numeric
assert _Union(String, Numeric) >= Float

expect_type_error(expected: type, actual: :symbol, message: <<~ERROR)
Type mismatch
Expand Down

0 comments on commit e6d5e01

Please sign in to comment.