dry-types 0.15.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +10 -0
- data/.github/ISSUE_TEMPLATE/---bug-report.md +34 -0
- data/.github/ISSUE_TEMPLATE/---feature-request.md +18 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +18 -2
- data/.travis.yml +10 -5
- data/.yardopts +6 -2
- data/CHANGELOG.md +186 -3
- data/Gemfile +11 -5
- data/README.md +4 -3
- data/Rakefile +4 -2
- data/benchmarks/hash_schemas.rb +10 -6
- data/benchmarks/lax_schema.rb +15 -0
- data/benchmarks/profile_invalid_input.rb +15 -0
- data/benchmarks/profile_lax_schema_valid.rb +16 -0
- data/benchmarks/profile_valid_input.rb +15 -0
- data/benchmarks/schema_valid_vs_invalid.rb +21 -0
- data/benchmarks/setup.rb +17 -0
- data/docsite/source/array-with-member.html.md +13 -0
- data/docsite/source/built-in-types.html.md +116 -0
- data/docsite/source/constraints.html.md +31 -0
- data/docsite/source/custom-types.html.md +93 -0
- data/docsite/source/default-values.html.md +91 -0
- data/docsite/source/enum.html.md +69 -0
- data/docsite/source/getting-started.html.md +57 -0
- data/docsite/source/hash-schemas.html.md +169 -0
- data/docsite/source/index.html.md +155 -0
- data/docsite/source/map.html.md +17 -0
- data/docsite/source/optional-values.html.md +96 -0
- data/docsite/source/sum.html.md +21 -0
- data/dry-types.gemspec +21 -19
- data/lib/dry-types.rb +2 -0
- data/lib/dry/types.rb +60 -17
- data/lib/dry/types/any.rb +21 -10
- data/lib/dry/types/array.rb +17 -1
- data/lib/dry/types/array/constructor.rb +32 -0
- data/lib/dry/types/array/member.rb +72 -13
- data/lib/dry/types/builder.rb +49 -5
- data/lib/dry/types/builder_methods.rb +43 -16
- data/lib/dry/types/coercions.rb +84 -19
- data/lib/dry/types/coercions/json.rb +22 -3
- data/lib/dry/types/coercions/params.rb +98 -30
- data/lib/dry/types/compiler.rb +35 -12
- data/lib/dry/types/constrained.rb +78 -27
- data/lib/dry/types/constrained/coercible.rb +36 -6
- data/lib/dry/types/constraints.rb +15 -1
- data/lib/dry/types/constructor.rb +77 -62
- data/lib/dry/types/constructor/function.rb +200 -0
- data/lib/dry/types/container.rb +5 -0
- data/lib/dry/types/core.rb +35 -14
- data/lib/dry/types/decorator.rb +37 -10
- data/lib/dry/types/default.rb +48 -16
- data/lib/dry/types/enum.rb +31 -16
- data/lib/dry/types/errors.rb +73 -7
- data/lib/dry/types/extensions.rb +6 -0
- data/lib/dry/types/extensions/maybe.rb +52 -5
- data/lib/dry/types/extensions/monads.rb +29 -0
- data/lib/dry/types/fn_container.rb +5 -0
- data/lib/dry/types/hash.rb +32 -14
- data/lib/dry/types/hash/constructor.rb +16 -3
- data/lib/dry/types/inflector.rb +2 -0
- data/lib/dry/types/json.rb +7 -5
- data/lib/dry/types/{safe.rb → lax.rb} +33 -16
- data/lib/dry/types/map.rb +70 -32
- data/lib/dry/types/meta.rb +51 -0
- data/lib/dry/types/module.rb +10 -5
- data/lib/dry/types/nominal.rb +105 -14
- data/lib/dry/types/options.rb +12 -25
- data/lib/dry/types/params.rb +14 -3
- data/lib/dry/types/predicate_inferrer.rb +197 -0
- data/lib/dry/types/predicate_registry.rb +34 -0
- data/lib/dry/types/primitive_inferrer.rb +97 -0
- data/lib/dry/types/printable.rb +5 -1
- data/lib/dry/types/printer.rb +70 -64
- data/lib/dry/types/result.rb +26 -0
- data/lib/dry/types/schema.rb +177 -80
- data/lib/dry/types/schema/key.rb +48 -35
- data/lib/dry/types/spec/types.rb +43 -6
- data/lib/dry/types/sum.rb +70 -21
- data/lib/dry/types/type.rb +49 -0
- data/lib/dry/types/version.rb +3 -1
- metadata +91 -62
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
title: Map
|
3
|
+
layout: gem-single
|
4
|
+
name: dry-types
|
5
|
+
---
|
6
|
+
|
7
|
+
`Map` describes a homogeneous hashmap. This means only types of keys and values are known. You can simply imagine a map input as a list of key-value pairs.
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
int_float_hash = Types::Hash.map(Types::Integer, Types::Float)
|
11
|
+
int_float_hash[100 => 300.0, 42 => 70.0]
|
12
|
+
# => {100=>300.0, 42=>70.0}
|
13
|
+
|
14
|
+
# Only accepts mappings of integers to floats
|
15
|
+
int_float_hash[name: 'Jane']
|
16
|
+
# => Dry::Types::MapError: input key :name is invalid: type?(Integer, :name)
|
17
|
+
```
|
@@ -0,0 +1,96 @@
|
|
1
|
+
---
|
2
|
+
title: Type Attributes
|
3
|
+
layout: gem-single
|
4
|
+
name: dry-types
|
5
|
+
---
|
6
|
+
|
7
|
+
Types themselves have optional attributes you can apply to get further functionality.
|
8
|
+
|
9
|
+
### Append `.optional` to a _Type_ to allow `nil`
|
10
|
+
|
11
|
+
By default, nil values raise an error:
|
12
|
+
|
13
|
+
``` ruby
|
14
|
+
Types::Strict::String[nil]
|
15
|
+
# => raises Dry::Types::ConstraintError
|
16
|
+
```
|
17
|
+
|
18
|
+
Add `.optional` and `nil` values become valid:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
optional_string = Types::Strict::String.optional
|
22
|
+
|
23
|
+
optional_string[nil]
|
24
|
+
# => nil
|
25
|
+
optional_string['something']
|
26
|
+
# => "something"
|
27
|
+
optional_string[123]
|
28
|
+
# raises Dry::Types::ConstraintError
|
29
|
+
```
|
30
|
+
|
31
|
+
`Types::String.optional` is just syntactic sugar for `Types::Strict::Nil | Types::Strict::String`.
|
32
|
+
|
33
|
+
### Handle optional values using Monads
|
34
|
+
|
35
|
+
The [dry-monads gem](/gems/dry-monads/) provides another approach to handling optional values by returning a [_Monad_](/gems/dry-monads/) object. This allows you to pass your type to a `Maybe(x)` block that only executes if `x` returns `Some` or `None`.
|
36
|
+
|
37
|
+
> NOTE: Requires the [dry-monads gem](/gems/dry-monads/) to be loaded.
|
38
|
+
|
39
|
+
1. Load the `:maybe` extension in your application.
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
require 'dry-types'
|
43
|
+
|
44
|
+
Dry::Types.load_extensions(:maybe)
|
45
|
+
module Types
|
46
|
+
include Dry.Types()
|
47
|
+
end
|
48
|
+
```
|
49
|
+
|
50
|
+
2. Append `.maybe` to a _Type_ to return a _Monad_ object
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
x = Types::Maybe::Strict::Integer[nil]
|
54
|
+
Maybe(x) { puts(x) }
|
55
|
+
|
56
|
+
x = Types::Maybe::Coercible::String[nil]
|
57
|
+
Maybe(x) { puts(x) }
|
58
|
+
|
59
|
+
x = Types::Maybe::Strict::Integer[123]
|
60
|
+
Maybe(x) { puts(x) }
|
61
|
+
|
62
|
+
x = Types::Maybe::Strict::String[123]
|
63
|
+
Maybe(x) { puts(x) }
|
64
|
+
```
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
Types::Maybe::Strict::Integer[nil] # None
|
68
|
+
Types::Maybe::Strict::Integer[123] # Some(123)
|
69
|
+
|
70
|
+
Types::Maybe::Coercible::Float[nil] # None
|
71
|
+
Types::Maybe::Coercible::Float['12.3'] # Some(12.3)
|
72
|
+
|
73
|
+
# 'Maybe' types can also accessed by calling '.maybe' on a regular type:
|
74
|
+
Types::Strict::Integer.maybe # equivalent to Types::Maybe::Strict::Integer
|
75
|
+
```
|
76
|
+
|
77
|
+
You can define your own optional types:
|
78
|
+
|
79
|
+
``` ruby
|
80
|
+
maybe_string = Types::Strict::String.maybe
|
81
|
+
|
82
|
+
maybe_string[nil]
|
83
|
+
# => None
|
84
|
+
|
85
|
+
maybe_string[nil].fmap(&:upcase)
|
86
|
+
# => None
|
87
|
+
|
88
|
+
maybe_string['something']
|
89
|
+
# => Some('something')
|
90
|
+
|
91
|
+
maybe_string['something'].fmap(&:upcase)
|
92
|
+
# => Some('SOMETHING')
|
93
|
+
|
94
|
+
maybe_string['something'].fmap(&:upcase).value_or('NOTHING')
|
95
|
+
# => "SOMETHING"
|
96
|
+
```
|
@@ -0,0 +1,21 @@
|
|
1
|
+
---
|
2
|
+
title: Sum
|
3
|
+
layout: gem-single
|
4
|
+
name: dry-types
|
5
|
+
order: 7
|
6
|
+
---
|
7
|
+
|
8
|
+
You can specify sum types using `|` operator, it is an explicit way of defining what the valid types of a value are.
|
9
|
+
|
10
|
+
For example `dry-types` defines the `Bool` type which is a sum consisting of the `True` and `False` types, expressed as `Types::True | Types::False`.
|
11
|
+
|
12
|
+
Another common case is defining that something can be either `nil` or something else:
|
13
|
+
|
14
|
+
``` ruby
|
15
|
+
nil_or_string = Types::Nil | Types::String
|
16
|
+
|
17
|
+
nil_or_string[nil] # => nil
|
18
|
+
nil_or_string["hello"] # => "hello"
|
19
|
+
|
20
|
+
nil_or_string[123] # raises Dry::Types::ConstraintError
|
21
|
+
```
|
data/dry-types.gemspec
CHANGED
@@ -1,45 +1,47 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
5
|
require 'dry/types/version'
|
4
6
|
|
5
7
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
8
|
+
spec.name = 'dry-types'
|
7
9
|
spec.version = Dry::Types::VERSION.dup
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
10
|
+
spec.authors = ['Piotr Solnica']
|
11
|
+
spec.email = ['piotr.solnica@gmail.com']
|
10
12
|
spec.license = 'MIT'
|
11
13
|
|
12
14
|
spec.summary = 'Type system for Ruby supporting coercions, constraints and complex types like structs, value objects, enums etc.'
|
13
15
|
spec.description = spec.summary
|
14
|
-
spec.homepage =
|
16
|
+
spec.homepage = 'https://github.com/dry-rb/dry-types'
|
15
17
|
|
16
18
|
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
17
19
|
# delete this section to allow pushing this gem to any host.
|
18
20
|
if spec.respond_to?(:metadata)
|
19
|
-
spec.metadata['allowed_push_host'] =
|
20
|
-
spec.metadata['changelog_uri'] =
|
21
|
-
spec.metadata['source_code_uri'] =
|
22
|
-
spec.metadata['bug_tracker_uri'] =
|
21
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
22
|
+
spec.metadata['changelog_uri'] = 'https://github.com/dry-rb/dry-types/blob/master/CHANGELOG.md'
|
23
|
+
spec.metadata['source_code_uri'] = 'https://github.com/dry-rb/dry-types'
|
24
|
+
spec.metadata['bug_tracker_uri'] = 'https://github.com/dry-rb/dry-types/issues'
|
23
25
|
else
|
24
|
-
raise
|
26
|
+
raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
|
25
27
|
end
|
26
28
|
|
27
29
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } - ['bin/console', 'bin/setup']
|
28
|
-
spec.bindir =
|
30
|
+
spec.bindir = 'exe'
|
29
31
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
|
-
spec.require_paths = [
|
31
|
-
spec.required_ruby_version =
|
32
|
+
spec.require_paths = ['lib']
|
33
|
+
spec.required_ruby_version = '>= 2.4.0'
|
32
34
|
|
33
35
|
spec.add_runtime_dependency 'concurrent-ruby', '~> 1.0'
|
34
|
-
spec.add_runtime_dependency 'dry-core', '~> 0.4', '>= 0.4.4'
|
35
|
-
spec.add_runtime_dependency 'dry-inflector', '~> 0.1', '>= 0.1.2'
|
36
36
|
spec.add_runtime_dependency 'dry-container', '~> 0.3'
|
37
|
+
spec.add_runtime_dependency 'dry-core', '~> 0.4', '>= 0.4.4'
|
37
38
|
spec.add_runtime_dependency 'dry-equalizer', '~> 0.2', '>= 0.2.2'
|
38
|
-
spec.add_runtime_dependency 'dry-
|
39
|
+
spec.add_runtime_dependency 'dry-inflector', '~> 0.1', '>= 0.1.2'
|
40
|
+
spec.add_runtime_dependency 'dry-logic', '~> 1.0', '>= 1.0.2'
|
39
41
|
|
40
|
-
spec.add_development_dependency
|
41
|
-
spec.add_development_dependency "rake", "~> 11.0"
|
42
|
-
spec.add_development_dependency "rspec", "~> 3.3"
|
42
|
+
spec.add_development_dependency 'bundler'
|
43
43
|
spec.add_development_dependency 'dry-monads', '~> 0.2'
|
44
|
+
spec.add_development_dependency 'rake', '~> 11.0'
|
45
|
+
spec.add_development_dependency 'rspec', '~> 3.3'
|
44
46
|
spec.add_development_dependency 'yard', '~> 0.9.5'
|
45
47
|
end
|
data/lib/dry-types.rb
CHANGED
data/lib/dry/types.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'bigdecimal'
|
2
4
|
require 'date'
|
3
5
|
require 'set'
|
@@ -22,13 +24,16 @@ require 'dry/types/module'
|
|
22
24
|
require 'dry/types/errors'
|
23
25
|
|
24
26
|
module Dry
|
27
|
+
# Main library namespace
|
28
|
+
#
|
29
|
+
# @api public
|
25
30
|
module Types
|
26
31
|
extend Dry::Core::Extensions
|
27
32
|
extend Dry::Core::ClassAttributes
|
28
33
|
extend Dry::Core::Deprecations[:'dry-types']
|
29
34
|
include Dry::Core::Constants
|
30
35
|
|
31
|
-
TYPE_SPEC_REGEX =
|
36
|
+
TYPE_SPEC_REGEX = /(.+)<(.+)>/.freeze
|
32
37
|
|
33
38
|
# @see Dry.Types
|
34
39
|
def self.module(*namespaces, default: :nominal, **aliases)
|
@@ -40,34 +45,51 @@ module Dry
|
|
40
45
|
|
41
46
|
# @api private
|
42
47
|
def self.included(*)
|
43
|
-
raise
|
48
|
+
raise 'Import Dry.Types, not Dry::Types'
|
44
49
|
end
|
45
50
|
|
51
|
+
# Return container with registered built-in type objects
|
52
|
+
#
|
46
53
|
# @return [Container{String => Nominal}]
|
54
|
+
#
|
55
|
+
# @api private
|
47
56
|
def self.container
|
48
57
|
@container ||= Container.new
|
49
58
|
end
|
50
59
|
|
60
|
+
# Check if a give type is registered
|
61
|
+
#
|
62
|
+
# @return [Boolean]
|
63
|
+
#
|
51
64
|
# @api private
|
52
65
|
def self.registered?(class_or_identifier)
|
53
66
|
container.key?(identifier(class_or_identifier))
|
54
67
|
end
|
55
68
|
|
69
|
+
# Register a new built-in type
|
70
|
+
#
|
56
71
|
# @param [String] name
|
57
72
|
# @param [Type] type
|
58
73
|
# @param [#call,nil] block
|
74
|
+
#
|
59
75
|
# @return [Container{String => Nominal}]
|
76
|
+
#
|
60
77
|
# @api private
|
61
78
|
def self.register(name, type = nil, &block)
|
62
79
|
container.register(name, type || block.call)
|
63
80
|
end
|
64
81
|
|
82
|
+
# Get a built-in type by its name
|
83
|
+
#
|
65
84
|
# @param [String,Class] name
|
85
|
+
#
|
66
86
|
# @return [Type,Class]
|
87
|
+
#
|
88
|
+
# @api public
|
67
89
|
def self.[](name)
|
68
90
|
type_map.fetch_or_store(name) do
|
69
91
|
case name
|
70
|
-
when String
|
92
|
+
when ::String
|
71
93
|
result = name.match(TYPE_SPEC_REGEX)
|
72
94
|
|
73
95
|
if result
|
@@ -76,7 +98,12 @@ module Dry
|
|
76
98
|
else
|
77
99
|
container[name]
|
78
100
|
end
|
79
|
-
when Class
|
101
|
+
when ::Class
|
102
|
+
warn(<<~DEPRECATION)
|
103
|
+
Using Dry::Types.[] with a class is deprecated, please use string identifiers: Dry::Types[Integer] -> Dry::Types['integer'].
|
104
|
+
If you're using dry-struct this means changing `attribute :counter, Integer` to `attribute :counter, Dry::Types['integer']` or to `attribute :counter, 'integer'`.
|
105
|
+
DEPRECATION
|
106
|
+
|
80
107
|
type_name = identifier(name)
|
81
108
|
|
82
109
|
if container.key?(type_name)
|
@@ -88,19 +115,29 @@ module Dry
|
|
88
115
|
end
|
89
116
|
end
|
90
117
|
|
118
|
+
# Infer a type identifier from the provided class
|
119
|
+
#
|
91
120
|
# @param [#to_s] klass
|
121
|
+
#
|
92
122
|
# @return [String]
|
93
123
|
def self.identifier(klass)
|
94
124
|
Inflector.underscore(klass).tr('/', '.')
|
95
125
|
end
|
96
126
|
|
127
|
+
# Cached type map
|
128
|
+
#
|
97
129
|
# @return [Concurrent::Map]
|
130
|
+
#
|
131
|
+
# @api private
|
98
132
|
def self.type_map
|
99
133
|
@type_map ||= Concurrent::Map.new
|
100
134
|
end
|
101
135
|
|
102
|
-
|
103
|
-
#
|
136
|
+
# List of type keys defined in {Dry::Types.container}
|
137
|
+
#
|
138
|
+
# @return [String]
|
139
|
+
#
|
140
|
+
# @api private
|
104
141
|
def self.type_keys
|
105
142
|
container.keys
|
106
143
|
end
|
@@ -112,8 +149,8 @@ module Dry
|
|
112
149
|
if container.keys.any? { |key| key.split('.')[0] == underscored }
|
113
150
|
raise NameError,
|
114
151
|
'dry-types does not define constants for default types. '\
|
115
|
-
'You can access the predefined types with [], e.g. Dry::Types["
|
116
|
-
'or generate a module with types using Dry
|
152
|
+
'You can access the predefined types with [], e.g. Dry::Types["integer"] '\
|
153
|
+
'or generate a module with types using Dry.Types()'
|
117
154
|
else
|
118
155
|
super
|
119
156
|
end
|
@@ -126,26 +163,26 @@ module Dry
|
|
126
163
|
#
|
127
164
|
# module Types
|
128
165
|
# # imports all types as constants, uses modules for namespaces
|
129
|
-
# include Dry::Types
|
166
|
+
# include Dry::Types()
|
130
167
|
# end
|
131
|
-
# #
|
168
|
+
# # strict types are exported by default
|
132
169
|
# Types::Integer
|
133
|
-
# # => #<Dry::Types[Nominal<Integer>]>
|
134
|
-
# Types::Strict::Integer
|
135
170
|
# # => #<Dry::Types[Constrained<Nominal<Integer> rule=[type?(Integer)]>]>
|
171
|
+
# Types::Nominal::Integer
|
172
|
+
# # => #<Dry::Types[Nominal<Integer>]>
|
136
173
|
#
|
137
174
|
# @example changing default types
|
138
175
|
#
|
139
176
|
# module Types
|
140
|
-
# include Dry::Types(default: :
|
177
|
+
# include Dry::Types(default: :nominal)
|
141
178
|
# end
|
142
179
|
# Types::Integer
|
143
|
-
# # => #<Dry::Types[
|
180
|
+
# # => #<Dry::Types[Nominal<Integer>]>
|
144
181
|
#
|
145
182
|
# @example cherry-picking namespaces
|
146
183
|
#
|
147
184
|
# module Types
|
148
|
-
# include Dry::Types
|
185
|
+
# include Dry::Types(:strict, :coercible)
|
149
186
|
# end
|
150
187
|
# # cherry-picking discards default types,
|
151
188
|
# # provide the :default option along with the list of
|
@@ -154,7 +191,7 @@ module Dry
|
|
154
191
|
#
|
155
192
|
# @example custom names
|
156
193
|
# module Types
|
157
|
-
# include Dry::Types
|
194
|
+
# include Dry::Types(coercible: :Kernel)
|
158
195
|
# end
|
159
196
|
# Types::Kernel::Integer
|
160
197
|
# # => #<Dry::Types[Constructor<Nominal<Integer> fn=Kernel.Integer>]>
|
@@ -162,12 +199,18 @@ module Dry
|
|
162
199
|
# @param [Array<Symbol>] namespaces List of type namespaces to export
|
163
200
|
# @param [Symbol] default Default namespace to export
|
164
201
|
# @param [Hash{Symbol => Symbol}] aliases Optional renamings, like strict: :Draconian
|
202
|
+
#
|
165
203
|
# @return [Dry::Types::Module]
|
166
204
|
#
|
167
|
-
# @see Dry::
|
205
|
+
# @see Dry::Types::Module
|
206
|
+
#
|
207
|
+
# @api public
|
208
|
+
#
|
209
|
+
# rubocop:disable Naming/MethodName
|
168
210
|
def self.Types(*namespaces, default: Types::Undefined, **aliases)
|
169
211
|
Types::Module.new(Types.container, *namespaces, default: default, **aliases)
|
170
212
|
end
|
213
|
+
# rubocop:enable Naming/MethodName
|
171
214
|
end
|
172
215
|
|
173
216
|
require 'dry/types/core' # load built-in types
|
data/lib/dry/types/any.rb
CHANGED
@@ -1,36 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
module Types
|
3
|
-
Any
|
5
|
+
# Any is a nominal type that defines Object as the primitive class
|
6
|
+
#
|
7
|
+
# This type is useful in places where you can't be specific about the type
|
8
|
+
# and anything is acceptable.
|
9
|
+
#
|
10
|
+
# @api public
|
11
|
+
class AnyClass < Nominal
|
4
12
|
def self.name
|
5
13
|
'Any'
|
6
14
|
end
|
7
15
|
|
16
|
+
# @api private
|
8
17
|
def initialize(**options)
|
9
18
|
super(::Object, options)
|
10
19
|
end
|
11
20
|
|
12
21
|
# @return [String]
|
22
|
+
#
|
23
|
+
# @api public
|
13
24
|
def name
|
14
25
|
'Any'
|
15
26
|
end
|
16
27
|
|
17
|
-
# @param [Object] any input is valid
|
18
|
-
# @return [true]
|
19
|
-
def valid?(_)
|
20
|
-
true
|
21
|
-
end
|
22
|
-
alias_method :===, :valid?
|
23
|
-
|
24
28
|
# @param [Hash] new_options
|
29
|
+
#
|
25
30
|
# @return [Type]
|
26
|
-
|
31
|
+
#
|
32
|
+
# @api public
|
33
|
+
def with(new_options)
|
27
34
|
self.class.new(**options, meta: @meta, **new_options)
|
28
35
|
end
|
29
36
|
|
30
37
|
# @return [Array]
|
38
|
+
#
|
39
|
+
# @api public
|
31
40
|
def to_ast(meta: true)
|
32
41
|
[:any, meta ? self.meta : EMPTY_HASH]
|
33
42
|
end
|
34
|
-
end
|
43
|
+
end
|
44
|
+
|
45
|
+
Any = AnyClass.new
|
35
46
|
end
|
36
47
|
end
|