types 0.2.0 → 0.4.0

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.
data/lib/types/method.rb CHANGED
@@ -1,46 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022-2025, by Samuel Williams.
22
5
 
23
- require_relative 'generic'
6
+ require_relative "generic"
24
7
 
25
8
  module Types
26
- # A method type attached to a receiver type.
9
+ # Represents a method type attached to a receiver type.
10
+ #
11
+ # ```ruby
12
+ # type = Types::Method(Types::String, Types::Integer, returns: Types::String)
13
+ # type.to_s # => "Method(String, Integer, returns: String)"
14
+ # ```
27
15
  class Method
28
16
  include Generic
29
17
 
18
+ # @parameter receiver_type [Type] The type of the receiver.
19
+ # @parameter argument_types [Array(Type)] The types of the method arguments.
20
+ # @parameter return_type [Type | Nil] The return type of the method.
30
21
  def initialize(receiver_type, argument_types, return_type)
31
22
  @receiver_type = receiver_type
32
23
  @argument_types = argument_types
33
24
  @return_type = return_type
34
25
  end
35
26
 
27
+ # @returns [Type] The type of the receiver.
36
28
  attr :receiver_type
29
+ # @returns [Array(Type)] The types of the method arguments.
37
30
  attr :argument_types
31
+ # @returns [Type | Nil] The return type of the method.
38
32
  attr :return_type
39
33
 
34
+ # @returns [Boolean] true if this is a composite type.
40
35
  def composite?
41
36
  true
42
37
  end
43
38
 
39
+ # @returns [String] the string representation of the method type.
44
40
  def to_s
45
41
  buffer = ::String.new
46
42
 
@@ -59,6 +55,18 @@ module Types
59
55
  return buffer
60
56
  end
61
57
 
58
+ # @returns [String] the RBS type string, e.g. `Method[Receiver, (Args) -> Return]`.
59
+ def to_rbs
60
+ argument_types = @argument_types.map(&:to_rbs).join(", ")
61
+ return_type = @return_type ? @return_type.to_rbs : "void"
62
+
63
+ return "Method[#{@receiver_type}, (#{argument_types}) -> #{return_type}]"
64
+ end
65
+
66
+ # Parses the input as a method or proc.
67
+ # @parameter input [Object] The value to parse.
68
+ # @returns [UnboundMethod, Proc] the parsed method or proc.
69
+ # @raises [ArgumentError] if the input cannot be converted to a method.
62
70
  def parse(input)
63
71
  case input
64
72
  when ::String
@@ -71,7 +79,12 @@ module Types
71
79
  end
72
80
  end
73
81
 
82
+ # Constructs a {Method} type from the given receiver, argument, and return types.
83
+ # @parameter receiver_type [Type] The type of the receiver.
84
+ # @parameter argument_types [Array(Type)] The types of the method arguments.
85
+ # @parameter returns [Type | Nil] The return type of the method.
86
+ # @returns [Method] a new {Method} type.
74
87
  def self.Method(receiver_type, *argument_types, returns: nil)
75
88
  Method.new(receiver_type, argument_types, returns)
76
89
  end
77
- end
90
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2025, by Samuel Williams.
5
+
6
+ require_relative "generic"
7
+
8
+ module Types
9
+ # Represents a named type that may not be defined yet.
10
+ #
11
+ # ```ruby
12
+ # type = Types::Named("CustomType")
13
+ # type.parse(value) # => value (pass-through)
14
+ # ```
15
+ class Named < Module
16
+ include Generic
17
+
18
+ # Initialize with a type name.
19
+ # @parameter name [String] The name of the type.
20
+ def initialize(name)
21
+ @name = name
22
+ end
23
+
24
+ # @returns [String] The name of the type.
25
+ attr :name
26
+
27
+ # @returns [Boolean] whether the type is absolute.
28
+ def absolute?
29
+ @name.start_with?("::")
30
+ end
31
+
32
+ # @returns [Boolean] whether the type is relative.
33
+ def relative?
34
+ !absolute?
35
+ end
36
+
37
+ # Parses the input by passing it through unchanged.
38
+ # @parameter input [Object] The value to parse.
39
+ # @returns [Object] The input value unchanged.
40
+ def parse(input)
41
+ if resolved = self.resolve
42
+ if resolved.respond_to?(:load)
43
+ return resolved.load(input)
44
+ elsif resolved.respond_to?(:parse)
45
+ return resolved.parse(input)
46
+ else
47
+ raise ArgumentError, "Type #{@name} does not implement .load or .parse!"
48
+ end
49
+ else
50
+ raise ArgumentError, "Unknown type: #{@name}"
51
+ end
52
+ end
53
+
54
+ # Resolves the named type to the actual Ruby type if it exists.
55
+ # @returns [Class | Module | Nil] The resolved Ruby type or nil if not found.
56
+ def resolve
57
+ Object.const_get(@name)
58
+ rescue NameError
59
+ nil
60
+ end
61
+
62
+ # @returns [String] the RBS type string using the name.
63
+ def to_rbs
64
+ @name
65
+ end
66
+
67
+ # @returns [String] the string representation of the named type.
68
+ def to_s
69
+ @name
70
+ end
71
+
72
+ def inspect
73
+ "<#{self.class} #{@name}>"
74
+ end
75
+
76
+ # @returns [Boolean] true if other is a Named type with the same name.
77
+ def == other
78
+ other.is_a?(Named) && @name == other.name
79
+ end
80
+
81
+ # @returns [Integer] hash code based on the name.
82
+ def hash
83
+ @name.hash
84
+ end
85
+
86
+ # @returns [Boolean] whether this type is composite.
87
+ def composite?
88
+ false
89
+ end
90
+
91
+ # Handles missing constants by creating nested Named types.
92
+ # This allows parsing of nested type signatures like Foo::Bar.
93
+ # @parameter name [Symbol] The name of the missing constant.
94
+ # @returns [Named] A Named type representing the nested unknown type.
95
+ def const_missing(name)
96
+ Named.new("#{@name}::#{name}")
97
+ end
98
+ end
99
+
100
+ # Constructs a {Named} type with the given name.
101
+ # @parameter name [String] The name of the type.
102
+ # @returns [Named] a new {Named} type.
103
+ def self.Named(name)
104
+ Named.new(name)
105
+ end
106
+ end
data/lib/types/nil.rb CHANGED
@@ -1,31 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022-2025, by Samuel Williams.
22
5
 
23
- require_relative 'generic'
6
+ require_relative "generic"
24
7
 
25
8
  module Types
9
+ # Represents the nil type.
10
+ #
11
+ # ```ruby
12
+ # type = Types::Nil
13
+ # type.parse("nil") # => nil
14
+ # ```
26
15
  module Nil
27
16
  extend Generic
28
17
 
18
+ # Parses the input as nil if it matches.
19
+ # @parameter input [Object] The value to parse.
20
+ # @returns [NilClass] nil if the input matches.
21
+ # @raises [ArgumentError] if the input cannot be converted to nil.
29
22
  def self.parse(input)
30
23
  if input =~ /nil|null/i
31
24
  return nil
@@ -33,5 +26,16 @@ module Types
33
26
  raise ArgumentError, "Cannot coerce #{input.inspect} into Nil!"
34
27
  end
35
28
  end
29
+
30
+ # @returns [String] the RBS type string, e.g. `nil`.
31
+ def self.to_rbs
32
+ "nil"
33
+ end
34
+
35
+ # Resolves to the actual Ruby NilClass.
36
+ # @returns [Class] The NilClass.
37
+ def self.resolve
38
+ ::NilClass
39
+ end
36
40
  end
37
41
  end
data/lib/types/numeric.rb CHANGED
@@ -1,31 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022-2025, by Samuel Williams.
22
5
 
23
- require_relative 'generic'
6
+ require_relative "generic"
24
7
 
25
8
  module Types
9
+ # Represents a numeric type (integer or float).
10
+ #
11
+ # ```ruby
12
+ # type = Types::Numeric
13
+ # type.parse("42") # => 42
14
+ # type.parse("3.14") # => 3.14
15
+ # ```
26
16
  module Numeric
27
17
  extend Generic
28
18
 
19
+ # Parses the input as a numeric value (integer or float).
20
+ # @parameter input [Object] The value to parse.
21
+ # @returns [Numeric] The parsed numeric value.
29
22
  def self.parse(input)
30
23
  case input
31
24
  when Numeric then input
data/lib/types/string.rb CHANGED
@@ -1,33 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022-2025, by Samuel Williams.
22
5
 
23
- require_relative 'generic'
6
+ require_relative "generic"
24
7
 
25
8
  module Types
9
+ # Represents a string type.
10
+ #
11
+ # ```ruby
12
+ # type = Types::String
13
+ # type.parse(42) # => "42"
14
+ # ```
26
15
  module String
27
16
  extend Generic
28
17
 
18
+ # Parses the input as a string.
19
+ # @parameter input [Object] The value to parse.
20
+ # @returns [String] The parsed string value.
29
21
  def self.parse(input)
30
22
  input.to_s
31
23
  end
24
+
25
+ # @returns [String] the RBS type string, e.g. `String`.
26
+ def self.to_rbs
27
+ "String"
28
+ end
29
+
30
+ # Resolves to the actual Ruby String class.
31
+ # @returns [Class] The String class.
32
+ def self.resolve
33
+ ::String
34
+ end
32
35
  end
33
36
  end
data/lib/types/symbol.rb CHANGED
@@ -1,33 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022-2025, by Samuel Williams.
22
5
 
23
- require_relative 'generic'
6
+ require_relative "generic"
24
7
 
25
8
  module Types
9
+ # Represents a symbol type.
10
+ #
11
+ # ```ruby
12
+ # type = Types::Symbol
13
+ # type.parse("foo") # => :foo
14
+ # ```
26
15
  module Symbol
27
16
  extend Generic
28
17
 
18
+ # Parses the input as a symbol.
19
+ # @parameter input [Object] The value to parse.
20
+ # @returns [Symbol] The parsed symbol value.
29
21
  def self.parse(input)
30
22
  input.to_sym
31
23
  end
24
+
25
+ # @returns [String] the RBS type string, e.g. `Symbol`.
26
+ def self.to_rbs
27
+ "Symbol"
28
+ end
29
+
30
+ # Resolves to the actual Ruby Symbol class.
31
+ # @returns [Class] The Symbol class.
32
+ def self.resolve
33
+ ::Symbol
34
+ end
32
35
  end
33
36
  end
data/lib/types/tuple.rb CHANGED
@@ -1,42 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022-2025, by Samuel Williams.
22
5
 
23
- require_relative 'generic'
24
- require 'json'
6
+ require_relative "generic"
7
+ require "json"
25
8
 
26
9
  module Types
10
+ # Represents a tuple type with specific item types.
11
+ #
12
+ # ```ruby
13
+ # type = Types::Tuple(Types::String, Types::Integer)
14
+ # type.parse(["foo", "42"]) # => ["foo", 42]
15
+ # ```
27
16
  class Tuple
28
17
  include Generic
29
18
 
19
+ # @parameter item_types [Array(Type)] The types of the tuple elements.
30
20
  def initialize(item_types)
31
21
  @item_types = item_types
32
22
  end
33
23
 
24
+ # @returns [Array(Type)] The types of the tuple elements.
34
25
  attr :item_types
35
26
 
27
+ # @returns [Boolean] true if this is a composite type.
36
28
  def composite?
37
29
  true
38
30
  end
39
31
 
32
+ # Parses the input as a tuple with the specified item types.
33
+ # @parameter input [Object] The value to parse.
34
+ # @returns [Array] The parsed tuple.
35
+ # @raises [ArgumentError] if the input cannot be converted to a tuple.
40
36
  def parse(input)
41
37
  case input
42
38
  when ::String
@@ -48,10 +44,22 @@ module Types
48
44
  end
49
45
  end
50
46
 
47
+ # Resolves to the actual Ruby Array class, since there is no direct support for tuples in Ruby.
48
+ # @returns [Class] The Array class.
49
+ def resolve
50
+ ::Array
51
+ end
52
+
53
+ # @returns [String] the string representation of the tuple type.
51
54
  def to_s
52
55
  "Tuple(#{@item_types.join(', ')})"
53
56
  end
54
57
 
58
+ # @returns [String] the RBS type string, e.g. `[String, Integer]`.
59
+ def to_rbs
60
+ "[#{@item_types.map(&:to_rbs).join(', ')}]"
61
+ end
62
+
55
63
  private
56
64
 
57
65
  def parse_string(input)
@@ -63,6 +71,9 @@ module Types
63
71
  end
64
72
  end
65
73
 
74
+ # Constructs a {Tuple} type from the given item types.
75
+ # @parameter item_types [Array(Type)] The types of the tuple elements.
76
+ # @returns [Tuple] a new {Tuple} type.
66
77
  def self.Tuple(*item_types)
67
78
  Tuple.new(item_types)
68
79
  end
data/lib/types/version.rb CHANGED
@@ -1,25 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022-2025, by Samuel Williams.
22
5
 
23
6
  module Types
24
- VERSION = "0.2.0"
7
+ VERSION = "0.4.0"
25
8
  end
data/lib/types.rb CHANGED
@@ -1,52 +1,66 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
3
+ # Released under the MIT License.
4
+ # Copyright, 2022-2025, by Samuel Williams.
22
5
 
23
- require_relative 'types/version'
6
+ require_relative "types/version"
24
7
 
25
- require_relative 'types/any'
26
- require_relative 'types/array'
27
- require_relative 'types/block'
28
- require_relative 'types/boolean'
29
- require_relative 'types/class'
30
- require_relative 'types/decimal'
31
- require_relative 'types/float'
32
- require_relative 'types/hash'
33
- require_relative 'types/integer'
34
- require_relative 'types/lambda'
35
- require_relative 'types/method'
36
- require_relative 'types/nil'
37
- require_relative 'types/numeric'
38
- require_relative 'types/string'
39
- require_relative 'types/symbol'
40
- require_relative 'types/tuple'
8
+ require_relative "types/any"
9
+ require_relative "types/array"
10
+ require_relative "types/block"
11
+ require_relative "types/boolean"
12
+ require_relative "types/class"
13
+ require_relative "types/decimal"
14
+ require_relative "types/float"
15
+ require_relative "types/hash"
16
+ require_relative "types/integer"
17
+ require_relative "types/interface"
18
+ require_relative "types/lambda"
19
+ require_relative "types/method"
20
+ require_relative "types/named"
21
+ require_relative "types/nil"
22
+ require_relative "types/numeric"
23
+ require_relative "types/string"
24
+ require_relative "types/symbol"
25
+ require_relative "types/tuple"
41
26
 
27
+ # @namespace
42
28
  module Types
43
- VALID_SIGNATURE = /\A[a-zA-Z\(\):, |]+\z/
29
+ # The main module for the types library.
30
+ #
31
+ # Provides parsing and construction of type signatures.
32
+ #
33
+ # ```ruby
34
+ # Types.parse("Array(String)") # => Types::Array(Types::String)
35
+ # ```
36
+ VALID_SIGNATURE = /\A[a-zA-Z0-9\(\):,_|\s]+\z/
44
37
 
38
+ # Parses a type signature string and returns the corresponding type instance.
39
+ # @parameter signature [String] The type signature to parse.
40
+ # @returns [Object] The type instance.
41
+ # @raises [ArgumentError] if the signature is invalid.
45
42
  def self.parse(signature)
46
43
  if signature =~ VALID_SIGNATURE
47
- eval(signature, binding)
44
+ # Replace leading :: with Top:: to handle absolute type paths
45
+ normalized_signature = signature.gsub(/(?<=\A|\W)::/, "TOP::")
46
+ eval(normalized_signature, binding)
48
47
  else
49
48
  raise ArgumentError, "Invalid type signature: #{signature.inspect}!"
50
49
  end
51
50
  end
51
+
52
+ # Handles absolute type paths by creating absolute Named types for unknown types.
53
+ module TOP
54
+ def self.const_missing(name)
55
+ Named.new("::#{name}")
56
+ end
57
+ end
58
+
59
+ # Handles missing constants by creating Named types for unknown types.
60
+ # This allows parsing of type signatures with unknown types.
61
+ # @parameter name [Symbol] The name of the missing constant.
62
+ # @returns [Named] A Named type representing the unknown type.
63
+ def self.const_missing(name)
64
+ Named(name.to_s)
65
+ end
52
66
  end
data/license.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright, 2022-2025, by Samuel Williams.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.