types 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/agent.md +47 -0
- data/context/usage.md +195 -0
- data/lib/types/any.rb +33 -46
- data/lib/types/array.rb +27 -20
- data/lib/types/block.rb +28 -20
- data/lib/types/boolean.rb +19 -20
- data/lib/types/class.rb +29 -20
- data/lib/types/decimal.rb +14 -22
- data/lib/types/float.rb +18 -20
- data/lib/types/generic.rb +17 -22
- data/lib/types/hash.rb +26 -20
- data/lib/types/integer.rb +18 -20
- data/lib/types/interface.rb +100 -0
- data/lib/types/lambda.rb +23 -21
- data/lib/types/method.rb +35 -22
- data/lib/types/nil.rb +18 -20
- data/lib/types/numeric.rb +13 -20
- data/lib/types/string.rb +17 -20
- data/lib/types/symbol.rb +17 -20
- data/lib/types/tuple.rb +26 -21
- data/lib/types/version.rb +3 -20
- data/lib/types.rb +34 -38
- data/license.md +21 -0
- data/readme.md +71 -0
- data.tar.gz.sig +0 -0
- metadata +36 -34
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d9009b2973c8d9b30fbc68da3eb4088ef28672339e593e63ed92f7f1685daf35
|
4
|
+
data.tar.gz: 45cbaae7e30b4603f59e7b95e8d85768edd8c8ded3df216c2c7087fdae839216
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1cbda8d764a40a9adb42358620e21a5091dd98dee66904d14e170a96f58fdfc744ad4c613beccb5ec0f52ec17ca2b61261f4a58c664e7eb5bbe41b7788f95f88
|
7
|
+
data.tar.gz: 34341cc300faea4cfb3053388d928d84b32432e128c17ba3c7641ea757d65fbaab706683352731e6b13c67620e0e7f9d32bc84a9957f390346e69b70fc9defc9
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/agent.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Agent
|
2
|
+
|
3
|
+
## Context
|
4
|
+
|
5
|
+
This section provides links to documentation from installed packages. It is automatically generated and may be updated by running `bake agent:context:install`.
|
6
|
+
|
7
|
+
**Important:** Before performing any code, documentation, or analysis tasks, always read and apply the full content of any relevant documentation referenced in the following sections. These context files contain authoritative standards and best practices for documentation, code style, and project-specific workflows. **Do not proceed with any actions until you have read and incorporated the guidance from relevant context files.**
|
8
|
+
|
9
|
+
### agent-context
|
10
|
+
|
11
|
+
Install and manage context files from Ruby gems.
|
12
|
+
|
13
|
+
#### [Usage Guide](.context/agent-context/usage.md)
|
14
|
+
|
15
|
+
`agent-context` is a tool that helps you discover and install contextual information from Ruby gems for AI agents. Gems can provide additional documentation, examples, and guidance in a `context/` ...
|
16
|
+
|
17
|
+
### decode
|
18
|
+
|
19
|
+
Code analysis for documentation generation.
|
20
|
+
|
21
|
+
#### [Getting Started with Decode](.context/decode/getting-started.md)
|
22
|
+
|
23
|
+
The Decode gem provides programmatic access to Ruby code structure and metadata. It can parse Ruby files and extract definitions, comments, and documentation pragmas, enabling code analysis, docume...
|
24
|
+
|
25
|
+
#### [Documentation Coverage](.context/decode/coverage.md)
|
26
|
+
|
27
|
+
This guide explains how to test and monitor documentation coverage in your Ruby projects using the Decode gem's built-in bake tasks.
|
28
|
+
|
29
|
+
#### [Ruby Documentation](.context/decode/ruby-documentation.md)
|
30
|
+
|
31
|
+
This guide covers documentation practices and pragmas supported by the Decode gem for documenting Ruby code. These pragmas provide structured documentation that can be parsed and used to generate A...
|
32
|
+
|
33
|
+
### sus
|
34
|
+
|
35
|
+
A fast and scalable test runner.
|
36
|
+
|
37
|
+
#### [Using Sus Testing Framework](.context/sus/usage.md)
|
38
|
+
|
39
|
+
Sus is a modern Ruby testing framework that provides a clean, BDD-style syntax for writing tests. It's designed to be fast, simple, and expressive.
|
40
|
+
|
41
|
+
#### [Mocking](.context/sus/mocking.md)
|
42
|
+
|
43
|
+
There are two types of mocking in sus: `receive` and `mock`. The `receive` matcher is a subset of full mocking and is used to set expectations on method calls, while `mock` can be used to replace m...
|
44
|
+
|
45
|
+
#### [Shared Test Behaviors and Fixtures](.context/sus/shared.md)
|
46
|
+
|
47
|
+
Sus provides shared test contexts which can be used to define common behaviours or tests that can be reused across one or more test files.
|
data/context/usage.md
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
# Usage
|
2
|
+
|
3
|
+
The Types gem provides abstract types for the Ruby programming language that can be used for documentation and evaluation purposes. It offers a simple and Ruby-compatible approach to type signatures, designed to work seamlessly with documentation tools and argument parsing.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
This gem provides a simple and Ruby-compatible approach to type information. It offers:
|
8
|
+
|
9
|
+
- Simple type signature parsing.
|
10
|
+
- String-to-value coercion.
|
11
|
+
- Documentation integration.
|
12
|
+
- RBS compatibility.
|
13
|
+
|
14
|
+
The types are designed to be a subset of Ruby's type system, making them easy to understand and use while remaining powerful enough for most use cases.
|
15
|
+
|
16
|
+
## How to Use Types
|
17
|
+
|
18
|
+
Types can be used directly as modules or classes:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
# Simple types
|
22
|
+
Types::String.parse("hello") # => "hello"
|
23
|
+
Types::Integer.parse("42") # => 42
|
24
|
+
Types::Float.parse("3.14") # => 3.14
|
25
|
+
Types::Boolean.parse("true") # => true
|
26
|
+
Types::Symbol.parse("hello") # => :hello
|
27
|
+
```
|
28
|
+
|
29
|
+
### Composite Types
|
30
|
+
|
31
|
+
For more complex types, you can create composite types:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
# Array with specific item type
|
35
|
+
array_type = Types::Array(Types::Integer)
|
36
|
+
array_type.parse(["1", "2", "3"]) # => [1, 2, 3]
|
37
|
+
|
38
|
+
# Hash with key and value types
|
39
|
+
hash_type = Types::Hash(Types::String, Types::Integer)
|
40
|
+
hash_type.parse("a:1,b:2") # => {"a" => 1, "b" => 2}
|
41
|
+
|
42
|
+
# Tuple types
|
43
|
+
tuple_type = Types::Tuple(Types::String, Types::Integer)
|
44
|
+
tuple_type.parse("hello,42") # => ["hello", 42]
|
45
|
+
```
|
46
|
+
|
47
|
+
### Union Types
|
48
|
+
|
49
|
+
You can create union types using the `|` operator:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
# String or Integer
|
53
|
+
string_or_int = Types::String | Types::Integer
|
54
|
+
string_or_int.parse("hello") # => "hello"
|
55
|
+
string_or_int.parse("42") # => 42
|
56
|
+
```
|
57
|
+
|
58
|
+
## How to Parse Types
|
59
|
+
|
60
|
+
The main way to parse type signatures is using `Types.parse`:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
# Simple types
|
64
|
+
Types.parse("String") # => Types::String
|
65
|
+
Types.parse("Integer") # => Types::Integer
|
66
|
+
Types.parse("Float") # => Types::Float
|
67
|
+
|
68
|
+
# Composite types
|
69
|
+
Types.parse("Array(String)") # => Types::Array(Types::String)
|
70
|
+
Types.parse("Hash(String, Integer)") # => Types::Hash(Types::String, Types::Integer)
|
71
|
+
Types.parse("Tuple(String, Integer)") # => Types::Tuple(Types::String, Types::Integer)
|
72
|
+
|
73
|
+
# Union types
|
74
|
+
Types.parse("String|Integer") # => Types::Any([Types::String, Types::Integer])
|
75
|
+
```
|
76
|
+
|
77
|
+
### Type Signature Format
|
78
|
+
|
79
|
+
The gem supports a subset of Ruby expressions for type signatures:
|
80
|
+
|
81
|
+
- Simple types: `String`, `Integer`, `Float`, `Boolean`, `Symbol`, `Nil`
|
82
|
+
- Composite types: `Array(Type)`, `Hash(KeyType, ValueType)`, `Tuple(Type1, Type2)`
|
83
|
+
- Union types: `Type1|Type2`
|
84
|
+
- Lambda types: `Lambda(ArgType, returns: ReturnType)`
|
85
|
+
|
86
|
+
### Validation
|
87
|
+
|
88
|
+
Type signatures are validated against a regex pattern:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
Types::VALID_SIGNATURE = /\A[a-zA-Z\(\):,_|\s]+\z/
|
92
|
+
```
|
93
|
+
|
94
|
+
Invalid signatures will raise an `ArgumentError`:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
Types.parse("Invalid@Type") # => ArgumentError: Invalid type signature: "Invalid@Type"!
|
98
|
+
```
|
99
|
+
|
100
|
+
## How to Use Types to Parse Strings into Values
|
101
|
+
|
102
|
+
Each type provides a `parse` method that can convert strings to typed values:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
# Integer parsing
|
106
|
+
Types::Integer.parse("42") # => 42
|
107
|
+
Types::Integer.parse("0") # => 0
|
108
|
+
Types::Integer.parse("-123") # => -123
|
109
|
+
|
110
|
+
# String parsing (converts any input to string)
|
111
|
+
Types::String.parse(42) # => "42"
|
112
|
+
Types::String.parse("hello") # => "hello"
|
113
|
+
|
114
|
+
# Float parsing
|
115
|
+
Types::Float.parse("3.14") # => 3.14
|
116
|
+
Types::Float.parse("0.0") # => 0.0
|
117
|
+
|
118
|
+
# Boolean parsing
|
119
|
+
Types::Boolean.parse("true") # => true
|
120
|
+
Types::Boolean.parse("false") # => false
|
121
|
+
Types::Boolean.parse("1") # => true
|
122
|
+
Types::Boolean.parse("0") # => false
|
123
|
+
```
|
124
|
+
|
125
|
+
### Array Parsing
|
126
|
+
|
127
|
+
Arrays can parse both string representations and actual arrays:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
array_type = Types::Array(Types::Integer)
|
131
|
+
|
132
|
+
# Parse string representation
|
133
|
+
array_type.parse("1,2,3") # => [1, 2, 3]
|
134
|
+
array_type.parse("'a','b','c'") # => ["a", "b", "c"]
|
135
|
+
|
136
|
+
# Parse actual array
|
137
|
+
array_type.parse(["1", "2", "3"]) # => [1, 2, 3]
|
138
|
+
```
|
139
|
+
|
140
|
+
### Hash Parsing
|
141
|
+
|
142
|
+
Hashes can parse string representations:
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
hash_type = Types::Hash(Types::String, Types::Integer)
|
146
|
+
|
147
|
+
# Parse string representation
|
148
|
+
hash_type.parse("a:1,b:2,c:3") # => {"a" => 1, "b" => 2, "c" => 3}
|
149
|
+
```
|
150
|
+
|
151
|
+
### Error Handling
|
152
|
+
|
153
|
+
Parsing methods will raise `ArgumentError` for invalid inputs:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
Types::Integer.parse("not_a_number") # => ArgumentError
|
157
|
+
Types::Array(Types::Integer).parse("invalid") # => ArgumentError
|
158
|
+
```
|
159
|
+
|
160
|
+
### Practical Example: Command Line Arguments
|
161
|
+
|
162
|
+
This is particularly useful for parsing command line arguments:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
def parse_arguments(arguments)
|
166
|
+
config = {
|
167
|
+
port: Types::Integer.parse(arguments[:port] || "8080"),
|
168
|
+
host: Types::String.parse(arguments[:host] || "localhost"),
|
169
|
+
debug: Types::Boolean.parse(arguments[:debug] || "false"),
|
170
|
+
tags: Types::Array(Types::String).parse(arguments[:tags] || "")
|
171
|
+
}
|
172
|
+
|
173
|
+
config
|
174
|
+
end
|
175
|
+
|
176
|
+
# Usage
|
177
|
+
parse_arguments(port: "3000", tags: "api,web,admin")
|
178
|
+
# => {port: 3000, host: "localhost", debug: false, tags: ["api", "web", "admin"]}
|
179
|
+
```
|
180
|
+
|
181
|
+
### Integration with Documentation
|
182
|
+
|
183
|
+
The types work seamlessly with documentation tools that use `@parameter` and `@returns` comments:
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
# @parameter port [Integer] The port number to bind to
|
187
|
+
# @parameter host [String] The host address to bind to
|
188
|
+
# @parameter tags [Array(String)] List of tags to apply
|
189
|
+
# @returns [Hash] Configuration hash
|
190
|
+
def create_server(port, host, tags)
|
191
|
+
# Implementation here
|
192
|
+
end
|
193
|
+
```
|
194
|
+
|
195
|
+
This provides a clean, consistent way to handle type information throughout your Ruby applications.
|
data/lib/types/any.rb
CHANGED
@@ -1,53 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
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
|
-
#
|
25
|
-
#
|
26
|
-
# ```ruby
|
27
|
-
# type = Bake::Types::Any(Bake::Types::String, Bake::Types::Integer)
|
28
|
-
# ```
|
7
|
+
# Represents a union of multiple types. The first type to match the input is used.
|
29
8
|
#
|
9
|
+
# ```ruby
|
10
|
+
# type = Types::Any(Types::String, Types::Integer)
|
11
|
+
# ```
|
30
12
|
class Any
|
31
13
|
# Initialize the instance with an array of types.
|
32
|
-
# @parameter types [Array]
|
14
|
+
# @parameter types [Array] The array of types.
|
33
15
|
def initialize(types)
|
34
16
|
@types = types
|
35
17
|
end
|
36
|
-
|
37
|
-
#
|
38
|
-
# @parameter other [Type]
|
18
|
+
|
19
|
+
# @returns [Any] a new {Any} with the other type appended.
|
20
|
+
# @parameter other [Type] The type instance to append.
|
39
21
|
def | other
|
40
22
|
self.class.new([*@types, other])
|
41
23
|
end
|
42
|
-
|
43
|
-
#
|
44
|
-
# @returns [Boolean] true if any of the listed types is `composite?`.
|
24
|
+
|
25
|
+
# @returns [Boolean] true if any of the listed types is composite.
|
45
26
|
def composite?
|
46
|
-
@types.any?{|type| type.composite?}
|
27
|
+
@types.any? {|type| type.composite?}
|
47
28
|
end
|
48
|
-
|
49
|
-
#
|
50
|
-
# @parameter input [String] the input to parse
|
29
|
+
|
30
|
+
# Parses the input using the listed types in order, returning the first one that succeeds.
|
31
|
+
# @parameter input [String] the input to parse.
|
32
|
+
# @returns [Object] the parsed value.
|
33
|
+
# @raises [ArgumentError] if no type can parse the input.
|
51
34
|
def parse(input)
|
52
35
|
@types.each do |type|
|
53
36
|
return type.parse(input)
|
@@ -62,25 +45,29 @@ module Types
|
|
62
45
|
end
|
63
46
|
end
|
64
47
|
|
65
|
-
#
|
48
|
+
# Accepts any value as a class type.
|
66
49
|
def self.parse(value)
|
67
50
|
value
|
68
51
|
end
|
69
52
|
|
70
|
-
#
|
53
|
+
# @returns [String] a readable string representation of the listed types.
|
71
54
|
def to_s
|
72
|
-
|
55
|
+
if @types.empty?
|
56
|
+
"Any()"
|
57
|
+
else
|
58
|
+
"#{@types.join(' | ')}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# @returns [String] the RBS type string, e.g. `String | Integer`.
|
63
|
+
def to_rbs
|
64
|
+
@types.map(&:to_rbs).join(" | ")
|
73
65
|
end
|
74
66
|
end
|
75
67
|
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
# Any(Integer, String)
|
80
|
-
# ```
|
81
|
-
#
|
82
|
-
# See [Any.initialize](#Bake::Types::Any::initialize).
|
83
|
-
#
|
68
|
+
# Constructs an {Any} type from the given types.
|
69
|
+
# @parameter types [Array(Type)] The types to include in the union.
|
70
|
+
# @returns [Any] a new {Any} type.
|
84
71
|
def self.Any(*types)
|
85
72
|
Any.new(types)
|
86
73
|
end
|
data/lib/types/array.rb
CHANGED
@@ -1,43 +1,41 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
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
|
6
|
+
require_relative "generic"
|
24
7
|
|
25
8
|
module Types
|
9
|
+
# Represents an array type with a specific item type.
|
10
|
+
#
|
11
|
+
# ```ruby
|
12
|
+
# type = Types::Array(Types::Integer)
|
13
|
+
# type.parse(["1", "2"]) # => [1, 2]
|
14
|
+
# ```
|
26
15
|
class Array
|
27
16
|
include Generic
|
28
17
|
|
18
|
+
# @parameter item_type [Type] The type of the array elements.
|
29
19
|
def initialize(item_type)
|
30
20
|
@item_type = item_type
|
31
21
|
end
|
32
22
|
|
23
|
+
# @returns [Boolean] true if this is a composite type.
|
33
24
|
def composite?
|
34
25
|
true
|
35
26
|
end
|
36
27
|
|
28
|
+
# Maps the given values using the item type's parse method.
|
29
|
+
# @parameter values [Array] The values to map.
|
30
|
+
# @returns [Array] The mapped array.
|
37
31
|
def map(values)
|
38
32
|
values.map{|value| @item_type.parse(value)}
|
39
33
|
end
|
40
34
|
|
35
|
+
# Parses the input as an array with the specified item type.
|
36
|
+
# @parameter input [Object] The value to parse.
|
37
|
+
# @returns [Array] The parsed array.
|
38
|
+
# @raises [ArgumentError] if the input cannot be converted to an array.
|
41
39
|
def parse(input)
|
42
40
|
case input
|
43
41
|
when ::String
|
@@ -49,10 +47,16 @@ module Types
|
|
49
47
|
end
|
50
48
|
end
|
51
49
|
|
50
|
+
# @returns [String] the string representation of the array type.
|
52
51
|
def to_s
|
53
52
|
"Array(#{@item_type})"
|
54
53
|
end
|
55
54
|
|
55
|
+
# @returns [String] the RBS type string, e.g. `Array[String]`.
|
56
|
+
def to_rbs
|
57
|
+
"Array[#{@item_type.to_rbs}]"
|
58
|
+
end
|
59
|
+
|
56
60
|
private
|
57
61
|
|
58
62
|
def parse_string(input)
|
@@ -64,6 +68,9 @@ module Types
|
|
64
68
|
end
|
65
69
|
end
|
66
70
|
|
71
|
+
# Constructs an {Array} type from the given item type.
|
72
|
+
# @parameter item_type [Type] The type of the array elements.
|
73
|
+
# @returns [Array] a new {Array} type.
|
67
74
|
def self.Array(item_type = Any)
|
68
75
|
Array.new(item_type)
|
69
76
|
end
|
data/lib/types/block.rb
CHANGED
@@ -1,43 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
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
|
6
|
+
require_relative "method"
|
24
7
|
|
25
8
|
module Types
|
9
|
+
# Represents a block (Proc) type with argument and return types.
|
10
|
+
#
|
11
|
+
# ```ruby
|
12
|
+
# type = Types::Block(Types::String, Types::Integer, returns: Types::String)
|
13
|
+
# type.to_s # => "Block(String, Integer, returns: String)"
|
14
|
+
# ```
|
26
15
|
class Block
|
27
16
|
include Generic
|
28
17
|
|
18
|
+
# @parameter argument_types [Array(Type)] The types of the block arguments.
|
19
|
+
# @parameter return_type [Type | Nil] The return type of the block.
|
29
20
|
def initialize(argument_types, return_type)
|
30
21
|
@argument_types = argument_types
|
31
22
|
@return_type = return_type
|
32
23
|
end
|
33
24
|
|
25
|
+
# @returns [Array(Type)] The types of the block arguments.
|
34
26
|
attr :argument_types
|
27
|
+
|
28
|
+
# @returns [Type | Nil] The return type of the block.
|
35
29
|
attr :return_type
|
36
30
|
|
31
|
+
# @returns [Boolean] true if this is a composite type.
|
37
32
|
def composite?
|
38
33
|
true
|
39
34
|
end
|
40
35
|
|
36
|
+
# @returns [String] the string representation of the block type.
|
41
37
|
def to_s
|
42
38
|
if @return_type
|
43
39
|
"Block(#{@argument_types.join(', ')}, returns: #{@return_type})"
|
@@ -45,8 +41,20 @@ module Types
|
|
45
41
|
"Block(#{@argument_types.join(', ')})"
|
46
42
|
end
|
47
43
|
end
|
44
|
+
|
45
|
+
# @returns [String] the RBS type string, e.g. `Proc[(String, Integer) -> String]`.
|
46
|
+
def to_rbs
|
47
|
+
argument_types = @argument_types.map(&:to_rbs).join(", ")
|
48
|
+
return_type = @return_type ? @return_type.to_rbs : "void"
|
49
|
+
|
50
|
+
return "Proc[(#{argument_types}) -> #{return_type}]"
|
51
|
+
end
|
48
52
|
end
|
49
53
|
|
54
|
+
# Constructs a {Block} type from the given argument and return types.
|
55
|
+
# @parameter argument_types [Array(Type)] The types of the block arguments.
|
56
|
+
# @parameter returns [Type | Nil] The return type of the block.
|
57
|
+
# @returns [Block] a new {Block} type.
|
50
58
|
def self.Block(*argument_types, returns: nil)
|
51
59
|
Block.new(argument_types, returns)
|
52
60
|
end
|
data/lib/types/boolean.rb
CHANGED
@@ -1,31 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
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
|
6
|
+
require_relative "generic"
|
24
7
|
|
25
8
|
module Types
|
9
|
+
# Represents a boolean type.
|
10
|
+
#
|
11
|
+
# ```ruby
|
12
|
+
# type = Types::Boolean
|
13
|
+
# type.parse("true") # => true
|
14
|
+
# type.parse("no") # => false
|
15
|
+
# ```
|
26
16
|
module Boolean
|
27
17
|
extend Generic
|
28
18
|
|
19
|
+
# Parses the input as a boolean.
|
20
|
+
# @parameter input [Object] The value to parse.
|
21
|
+
# @returns [Boolean] The parsed boolean value.
|
22
|
+
# @raises [ArgumentError] if the input cannot be converted to a boolean.
|
29
23
|
def self.parse(input)
|
30
24
|
if input =~ /t(rue)?|y(es)?/i
|
31
25
|
return true
|
@@ -35,5 +29,10 @@ module Types
|
|
35
29
|
raise ArgumentError, "Cannot coerce #{input.inspect} into Boolean!"
|
36
30
|
end
|
37
31
|
end
|
32
|
+
|
33
|
+
# @returns [String] the RBS type string, e.g. `bool`.
|
34
|
+
def self.to_rbs
|
35
|
+
"bool"
|
36
|
+
end
|
38
37
|
end
|
39
38
|
end
|
data/lib/types/class.rb
CHANGED
@@ -1,42 +1,38 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
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
|
6
|
+
require_relative "generic"
|
24
7
|
|
25
8
|
module Types
|
9
|
+
# Represents a class type, optionally constrained to a base class.
|
10
|
+
#
|
11
|
+
# ```ruby
|
12
|
+
# type = Types::Class(String)
|
13
|
+
# type.parse("Array") # => Array
|
14
|
+
# ```
|
26
15
|
class Class
|
27
16
|
extend Generic
|
28
17
|
include Generic
|
29
18
|
|
19
|
+
# @parameter base [Class] The base class constraint.
|
30
20
|
def initialize(base)
|
31
21
|
@base = base
|
32
22
|
end
|
33
23
|
|
24
|
+
# @returns [Class] the base class constraint.
|
34
25
|
attr :base
|
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 class, optionally checking the base class constraint.
|
33
|
+
# @parameter input [String] The class name to parse.
|
34
|
+
# @returns [Class] the parsed class.
|
35
|
+
# @raises [ArgumentError] if the class is not a subclass of the base.
|
40
36
|
def parse(input)
|
41
37
|
klass = Object.const_get(input)
|
42
38
|
|
@@ -47,10 +43,20 @@ module Types
|
|
47
43
|
return klass
|
48
44
|
end
|
49
45
|
|
46
|
+
# @returns [Boolean] false for the class type itself.
|
50
47
|
def self.composite?
|
51
48
|
false
|
52
49
|
end
|
53
50
|
|
51
|
+
# @returns [String] the RBS type string, e.g. `Class`.
|
52
|
+
def to_rbs
|
53
|
+
"Class"
|
54
|
+
end
|
55
|
+
|
56
|
+
# Parses the input as a class, raising if not a class.
|
57
|
+
# @parameter input [String] The class name to parse.
|
58
|
+
# @returns [Class] the parsed class.
|
59
|
+
# @raises [ArgumentError] if the constant is not a class.
|
54
60
|
def self.parse(input)
|
55
61
|
klass = Object.const_get(input)
|
56
62
|
|
@@ -62,6 +68,9 @@ module Types
|
|
62
68
|
end
|
63
69
|
end
|
64
70
|
|
71
|
+
# Constructs a {Class} type with an optional base class constraint.
|
72
|
+
# @parameter base [Class] The base class constraint.
|
73
|
+
# @returns [Class] a new {Class} type.
|
65
74
|
def self.Class(base = Object)
|
66
75
|
Class.new(base)
|
67
76
|
end
|