domainic-type 0.1.0.alpha.2.1.0 → 0.1.0.alpha.3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/LICENSE +1 -1
- data/README.md +28 -4
- data/lib/domainic/type/accessors.rb +41 -0
- data/lib/domainic/type/behavior/enumerable_behavior.rb +262 -0
- data/lib/domainic/type/behavior/numeric_behavior.rb +340 -0
- data/lib/domainic/type/behavior/sizable_behavior.rb +246 -0
- data/lib/domainic/type/behavior/string_behavior.rb +379 -0
- data/lib/domainic/type/behavior.rb +239 -0
- data/lib/domainic/type/config/registry.yml +101 -0
- data/lib/domainic/type/constraint/behavior.rb +342 -0
- data/lib/domainic/type/constraint/constraints/all_constraint.rb +81 -0
- data/lib/domainic/type/constraint/constraints/and_constraint.rb +105 -0
- data/lib/domainic/type/constraint/constraints/any_constraint.rb +83 -0
- data/lib/domainic/type/constraint/constraints/case_constraint.rb +104 -0
- data/lib/domainic/type/constraint/constraints/character_set_constraint.rb +111 -0
- data/lib/domainic/type/constraint/constraints/divisibility_constraint.rb +126 -0
- data/lib/domainic/type/constraint/constraints/emptiness_constraint.rb +69 -0
- data/lib/domainic/type/constraint/constraints/equality_constraint.rb +75 -0
- data/lib/domainic/type/constraint/constraints/finiteness_constraint.rb +123 -0
- data/lib/domainic/type/constraint/constraints/inclusion_constraint.rb +74 -0
- data/lib/domainic/type/constraint/constraints/match_pattern_constraint.rb +87 -0
- data/lib/domainic/type/constraint/constraints/method_presence_constraint.rb +72 -0
- data/lib/domainic/type/constraint/constraints/none_constraint.rb +83 -0
- data/lib/domainic/type/constraint/constraints/nor_constraint.rb +105 -0
- data/lib/domainic/type/constraint/constraints/not_constraint.rb +76 -0
- data/lib/domainic/type/constraint/constraints/or_constraint.rb +106 -0
- data/lib/domainic/type/constraint/constraints/ordering_constraint.rb +75 -0
- data/lib/domainic/type/constraint/constraints/parity_constraint.rb +102 -0
- data/lib/domainic/type/constraint/constraints/polarity_constraint.rb +147 -0
- data/lib/domainic/type/constraint/constraints/range_constraint.rb +135 -0
- data/lib/domainic/type/constraint/constraints/type_constraint.rb +110 -0
- data/lib/domainic/type/constraint/constraints/uniqueness_constraint.rb +69 -0
- data/lib/domainic/type/constraint/resolver.rb +172 -0
- data/lib/domainic/type/constraint/set.rb +266 -0
- data/lib/domainic/type/definitions.rb +364 -0
- data/lib/domainic/type/types/core/array_type.rb +48 -0
- data/lib/domainic/type/types/core/float_type.rb +39 -0
- data/lib/domainic/type/types/core/hash_type.rb +143 -0
- data/lib/domainic/type/types/core/integer_type.rb +38 -0
- data/lib/domainic/type/types/core/string_type.rb +51 -0
- data/lib/domainic/type/types/core/symbol_type.rb +51 -0
- data/lib/domainic/type/types/specification/anything_type.rb +22 -0
- data/lib/domainic/type/types/specification/duck_type.rb +55 -0
- data/lib/domainic/type/types/specification/enum_type.rb +26 -0
- data/lib/domainic/type/types/specification/union_type.rb +26 -0
- data/lib/domainic/type/types/specification/void_type.rb +12 -0
- data/lib/domainic/type.rb +7 -0
- data/lib/domainic-type.rb +3 -0
- data/sig/domainic/type/accessors.rbs +22 -0
- data/sig/domainic/type/behavior/enumerable_behavior.rbs +238 -0
- data/sig/domainic/type/behavior/numeric_behavior.rbs +299 -0
- data/sig/domainic/type/behavior/sizable_behavior.rbs +218 -0
- data/sig/domainic/type/behavior/string_behavior.rbs +315 -0
- data/sig/domainic/type/behavior.rbs +153 -0
- data/sig/domainic/type/constraint/behavior.rbs +258 -0
- data/sig/domainic/type/constraint/constraints/all_constraint.rbs +55 -0
- data/sig/domainic/type/constraint/constraints/and_constraint.rbs +72 -0
- data/sig/domainic/type/constraint/constraints/any_constraint.rbs +57 -0
- data/sig/domainic/type/constraint/constraints/case_constraint.rbs +73 -0
- data/sig/domainic/type/constraint/constraints/character_set_constraint.rbs +82 -0
- data/sig/domainic/type/constraint/constraints/divisibility_constraint.rbs +91 -0
- data/sig/domainic/type/constraint/constraints/emptiness_constraint.rbs +54 -0
- data/sig/domainic/type/constraint/constraints/equality_constraint.rbs +60 -0
- data/sig/domainic/type/constraint/constraints/finiteness_constraint.rbs +82 -0
- data/sig/domainic/type/constraint/constraints/inclusion_constraint.rbs +59 -0
- data/sig/domainic/type/constraint/constraints/match_pattern_constraint.rbs +66 -0
- data/sig/domainic/type/constraint/constraints/method_presence_constraint.rbs +51 -0
- data/sig/domainic/type/constraint/constraints/none_constraint.rbs +57 -0
- data/sig/domainic/type/constraint/constraints/nor_constraint.rbs +72 -0
- data/sig/domainic/type/constraint/constraints/not_constraint.rbs +56 -0
- data/sig/domainic/type/constraint/constraints/or_constraint.rbs +74 -0
- data/sig/domainic/type/constraint/constraints/ordering_constraint.rbs +60 -0
- data/sig/domainic/type/constraint/constraints/parity_constraint.rbs +71 -0
- data/sig/domainic/type/constraint/constraints/polarity_constraint.rbs +101 -0
- data/sig/domainic/type/constraint/constraints/range_constraint.rbs +88 -0
- data/sig/domainic/type/constraint/constraints/type_constraint.rbs +86 -0
- data/sig/domainic/type/constraint/constraints/uniqueness_constraint.rbs +54 -0
- data/sig/domainic/type/constraint/resolver.rbs +117 -0
- data/sig/domainic/type/constraint/set.rbs +159 -0
- data/sig/domainic/type/definitions.rbs +304 -0
- data/sig/domainic/type/types/core/array_type.rbs +42 -0
- data/sig/domainic/type/types/core/float_type.rbs +33 -0
- data/sig/domainic/type/types/core/hash_type.rbs +107 -0
- data/sig/domainic/type/types/core/integer_type.rbs +32 -0
- data/sig/domainic/type/types/core/string_type.rbs +45 -0
- data/sig/domainic/type/types/core/symbol_type.rbs +45 -0
- data/sig/domainic/type/types/specification/anything_type.rbs +14 -0
- data/sig/domainic/type/types/specification/duck_type.rbs +41 -0
- data/sig/domainic/type/types/specification/enum_type.rbs +14 -0
- data/sig/domainic/type/types/specification/union_type.rbs +14 -0
- data/sig/domainic/type/types/specification/void_type.rbs +8 -0
- data/sig/domainic/type.rbs +5 -0
- data/sig/domainic-type.rbs +1 -0
- data/sig/manifest.yaml +2 -0
- metadata +108 -71
@@ -0,0 +1,364 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Domainic
|
4
|
+
module Type
|
5
|
+
# A module providing convenient factory methods for creating type instances.
|
6
|
+
#
|
7
|
+
# This module serves as a temporary access point for type creation in the Domainic::Type
|
8
|
+
# system, offering a collection of factory methods with consistent naming patterns.
|
9
|
+
# Each method creates and configures a specific type instance, with optional nilable
|
10
|
+
# variants and aliases for common use cases.
|
11
|
+
#
|
12
|
+
# @note This module is considered temporary and may be significantly altered or removed
|
13
|
+
# before the final release. It should not be considered part of the stable API.
|
14
|
+
#
|
15
|
+
# @example Basic type creation
|
16
|
+
# include Domainic::Type::Definitions
|
17
|
+
#
|
18
|
+
# string_type = _String()
|
19
|
+
# array_type = _Array()
|
20
|
+
# hash_type = _Hash()
|
21
|
+
#
|
22
|
+
# @example Creating nilable types
|
23
|
+
# nullable_string = _String?()
|
24
|
+
# nullable_array = _Array?()
|
25
|
+
#
|
26
|
+
# @example Using union types
|
27
|
+
# string_or_symbol = _Union(String, Symbol)
|
28
|
+
# boolean = _Boolean() # Union of TrueClass and FalseClass
|
29
|
+
#
|
30
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
31
|
+
# @since 0.1.0
|
32
|
+
module Definitions
|
33
|
+
# rubocop:disable Naming/MethodName
|
34
|
+
|
35
|
+
# Creates an AnythingType instance.
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# type = _Anything
|
39
|
+
#
|
40
|
+
# @param options [Hash] additional configuration options
|
41
|
+
#
|
42
|
+
# @return [Domainic::Type::AnythingType] the created type
|
43
|
+
# @rbs (**__todo__ options) -> AnythingType
|
44
|
+
def _Anything(**options)
|
45
|
+
require 'domainic/type/types/specification/anything_type'
|
46
|
+
Domainic::Type::AnythingType.new(**options)
|
47
|
+
end
|
48
|
+
alias _Any _Anything
|
49
|
+
|
50
|
+
# Creates an ArrayType instance.
|
51
|
+
#
|
52
|
+
# @example
|
53
|
+
# type = _Array
|
54
|
+
#
|
55
|
+
# @param options [Hash] additional configuration options
|
56
|
+
#
|
57
|
+
# @return [Domainic::Type::ArrayType] the created type
|
58
|
+
# @rbs (**__todo__ options) -> ArrayType
|
59
|
+
def _Array(**options)
|
60
|
+
require 'domainic/type/types/core/array_type'
|
61
|
+
Domainic::Type::ArrayType.new(**options)
|
62
|
+
end
|
63
|
+
alias _List _Array
|
64
|
+
|
65
|
+
# Creates a nilable ArrayType instance.
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# type = _Array?
|
69
|
+
#
|
70
|
+
# @param options [Hash] additional configuration options
|
71
|
+
#
|
72
|
+
# @return [Domainic::Type::UnionType] the created type (Array or NilClass)
|
73
|
+
# @rbs (**__todo__ options) -> UnionType
|
74
|
+
def _Array?(**options)
|
75
|
+
array = _Array(**options)
|
76
|
+
_Nilable(array)
|
77
|
+
end
|
78
|
+
alias _List? _Array?
|
79
|
+
|
80
|
+
# Creates a Boolean type.
|
81
|
+
#
|
82
|
+
# Represents a union of TrueClass and FalseClass.
|
83
|
+
#
|
84
|
+
# @example
|
85
|
+
# type = _Boolean
|
86
|
+
#
|
87
|
+
# @return [Domainic::Type::UnionType] the created type
|
88
|
+
# @rbs () -> UnionType
|
89
|
+
def _Boolean
|
90
|
+
_Union(TrueClass, FalseClass).freeze
|
91
|
+
end
|
92
|
+
alias _Bool _Boolean
|
93
|
+
|
94
|
+
# Creates a nilable Boolean type.
|
95
|
+
#
|
96
|
+
# @example
|
97
|
+
# type = _Boolean?
|
98
|
+
#
|
99
|
+
# @return [Domainic::Type::UnionType] the created type (TrueClass, FalseClass, or NilClass)
|
100
|
+
# @rbs () -> UnionType
|
101
|
+
def _Boolean?
|
102
|
+
_Nilable(_Boolean)
|
103
|
+
end
|
104
|
+
alias _Bool? _Boolean?
|
105
|
+
|
106
|
+
# Creates a DuckType instance.
|
107
|
+
#
|
108
|
+
# DuckType allows specifying behavior based on method availability.
|
109
|
+
#
|
110
|
+
# @example
|
111
|
+
# type = _Duck(respond_to: :to_s)
|
112
|
+
#
|
113
|
+
# @param options [Hash] additional configuration options
|
114
|
+
#
|
115
|
+
# @return [Domainic::Type::DuckType] the created type
|
116
|
+
# @rbs (**__todo__ options) -> DuckType
|
117
|
+
def _Duck(**options)
|
118
|
+
require 'domainic/type/types/specification/duck_type'
|
119
|
+
Domainic::Type::DuckType.new(**options)
|
120
|
+
end
|
121
|
+
alias _Interface _Duck
|
122
|
+
alias _Protocol _Duck
|
123
|
+
alias _RespondingTo _Duck
|
124
|
+
|
125
|
+
# Creates an EnumType instance.
|
126
|
+
#
|
127
|
+
# EnumType restricts values to a specific set of literals.
|
128
|
+
#
|
129
|
+
# @example
|
130
|
+
# type = _Enum(:red, :green, :blue)
|
131
|
+
#
|
132
|
+
# @param literals [Array<Object>] the allowed literals
|
133
|
+
# @param options [Hash] additional configuration options
|
134
|
+
#
|
135
|
+
# @return [Domainic::Type::EnumType] the created type
|
136
|
+
# @rbs (*untyped literals, **__todo__ options) -> EnumType
|
137
|
+
def _Enum(*literals, **options)
|
138
|
+
require 'domainic/type/types/specification/enum_type'
|
139
|
+
Domainic::Type::EnumType.new(*literals, **options)
|
140
|
+
end
|
141
|
+
alias _Literal _Enum
|
142
|
+
|
143
|
+
# Creates a nilable EnumType instance.
|
144
|
+
#
|
145
|
+
# @example
|
146
|
+
# type = _Enum?(:red, :green, :blue)
|
147
|
+
#
|
148
|
+
# @param literals [Array<Object>] the allowed literals
|
149
|
+
# @param options [Hash] additional configuration options
|
150
|
+
#
|
151
|
+
# @return [Domainic::Type::UnionType] the created type (Enum or NilClass)
|
152
|
+
# @rbs (*untyped literals, **__todo__ options) -> UnionType
|
153
|
+
def _Enum?(*literals, **options)
|
154
|
+
enum = _Enum(*literals, **options)
|
155
|
+
_Nilable(enum)
|
156
|
+
end
|
157
|
+
alias _Literal? _Enum?
|
158
|
+
|
159
|
+
# Creates a FloatType instance.
|
160
|
+
#
|
161
|
+
# @example
|
162
|
+
# type = _Float
|
163
|
+
#
|
164
|
+
# @param options [Hash] additional configuration options
|
165
|
+
#
|
166
|
+
# @return [Domainic::Type::FloatType] the created type
|
167
|
+
# @rbs (**__todo__ options) -> FloatType
|
168
|
+
def _Float(**options)
|
169
|
+
require 'domainic/type/types/core/float_type'
|
170
|
+
Domainic::Type::FloatType.new(**options)
|
171
|
+
end
|
172
|
+
alias _Decimal _Float
|
173
|
+
alias _Real _Float
|
174
|
+
|
175
|
+
# Creates a nilable FloatType instance.
|
176
|
+
#
|
177
|
+
# @example
|
178
|
+
# type = _Float?
|
179
|
+
#
|
180
|
+
# @param options [Hash] additional configuration options
|
181
|
+
#
|
182
|
+
# @return [Domainic::Type::UnionType] the created type (Float or NilClass)
|
183
|
+
# @rbs (**__todo__ options) -> UnionType
|
184
|
+
def _Float?(**options)
|
185
|
+
float = _Float(**options)
|
186
|
+
_Nilable(float)
|
187
|
+
end
|
188
|
+
alias _Decimal? _Float?
|
189
|
+
alias _Real? _Float?
|
190
|
+
|
191
|
+
# Creates a HashType instance.
|
192
|
+
#
|
193
|
+
# @example
|
194
|
+
# type = _Hash
|
195
|
+
#
|
196
|
+
# @param options [Hash] additional configuration options
|
197
|
+
#
|
198
|
+
# @return [Domainic::Type::HashType] the created type
|
199
|
+
# @rbs (**__todo__ options) -> HashType
|
200
|
+
def _Hash(**options)
|
201
|
+
require 'domainic/type/types/core/hash_type'
|
202
|
+
Domainic::Type::HashType.new(**options)
|
203
|
+
end
|
204
|
+
alias _Map _Hash
|
205
|
+
|
206
|
+
# Creates a nilable HashType instance.
|
207
|
+
#
|
208
|
+
# @example
|
209
|
+
# type = _Hash?
|
210
|
+
#
|
211
|
+
# @param options [Hash] additional configuration options
|
212
|
+
#
|
213
|
+
# @return [Domainic::Type::UnionType] the created type (Hash or NilClass)
|
214
|
+
# @rbs (**__todo__ options) -> UnionType
|
215
|
+
def _Hash?(**options)
|
216
|
+
hash = _Hash(**options)
|
217
|
+
_Nilable(hash)
|
218
|
+
end
|
219
|
+
alias _Map? _Hash?
|
220
|
+
|
221
|
+
# Creates an IntegerType instance.
|
222
|
+
#
|
223
|
+
# @example
|
224
|
+
# type = _Integer
|
225
|
+
#
|
226
|
+
# @param options [Hash] additional configuration options
|
227
|
+
#
|
228
|
+
# @return [Domainic::Type::IntegerType] the created type
|
229
|
+
# @rbs (**__todo__ options) -> IntegerType
|
230
|
+
def _Integer(**options)
|
231
|
+
require 'domainic/type/types/core/integer_type'
|
232
|
+
Domainic::Type::IntegerType.new(**options)
|
233
|
+
end
|
234
|
+
alias _Int _Integer
|
235
|
+
alias _Number _Integer
|
236
|
+
|
237
|
+
# Creates a nilable IntegerType instance.
|
238
|
+
#
|
239
|
+
# @example
|
240
|
+
# type = _Integer?
|
241
|
+
#
|
242
|
+
# @param options [Hash] additional configuration options
|
243
|
+
#
|
244
|
+
# @return [Domainic::Type::UnionType] the created type (Integer or NilClass)
|
245
|
+
# @rbs (**__todo__ options) -> UnionType
|
246
|
+
def _Integer?(**options)
|
247
|
+
integer = _Integer(**options)
|
248
|
+
_Nilable(integer)
|
249
|
+
end
|
250
|
+
alias _Int? _Integer?
|
251
|
+
alias _Number? _Integer?
|
252
|
+
|
253
|
+
# Creates a Nilable (nullable) type.
|
254
|
+
#
|
255
|
+
# Combines one or more types with `NilClass` to allow nil values.
|
256
|
+
#
|
257
|
+
# @example
|
258
|
+
# type = _Nilable(String, Symbol)
|
259
|
+
#
|
260
|
+
# @param types [Array<Class, Module, Behavior>] the base types
|
261
|
+
# @param options [Hash] additional configuration options
|
262
|
+
#
|
263
|
+
# @return [Domainic::Type::UnionType] the created type (NilClass or other specified types)
|
264
|
+
# @rbs (*Class | Module | Behavior[untyped, untyped, untyped] types, **__todo__ options) -> UnionType
|
265
|
+
def _Nilable(*types, **options)
|
266
|
+
_Union(NilClass, *types, **options)
|
267
|
+
end
|
268
|
+
alias _Nullable _Nilable
|
269
|
+
|
270
|
+
# Creates a StringType instance.
|
271
|
+
#
|
272
|
+
# @example
|
273
|
+
# type = _String
|
274
|
+
#
|
275
|
+
# @param options [Hash] additional configuration options
|
276
|
+
#
|
277
|
+
# @return [Domainic::Type::StringType] the created type
|
278
|
+
# @rbs (**__todo__ options) -> StringType
|
279
|
+
def _String(**options)
|
280
|
+
require 'domainic/type/types/core/string_type'
|
281
|
+
Domainic::Type::StringType.new(**options)
|
282
|
+
end
|
283
|
+
alias _Text _String
|
284
|
+
|
285
|
+
# Creates a nilable StringType instance.
|
286
|
+
#
|
287
|
+
# @example
|
288
|
+
# type = _String?
|
289
|
+
#
|
290
|
+
# @param options [Hash] additional configuration options
|
291
|
+
#
|
292
|
+
# @return [Domainic::Type::UnionType] the created type (String or NilClass)
|
293
|
+
# @rbs (**__todo__ options) -> UnionType
|
294
|
+
def _String?(**options)
|
295
|
+
string = _String(**options)
|
296
|
+
_Nilable(string)
|
297
|
+
end
|
298
|
+
alias _Text? _String?
|
299
|
+
|
300
|
+
# Creates a SymbolType instance.
|
301
|
+
#
|
302
|
+
# @example
|
303
|
+
# type = _Symbol
|
304
|
+
#
|
305
|
+
# @param options [Hash] additional configuration options
|
306
|
+
#
|
307
|
+
# @return [Domainic::Type::SymbolType] the created type
|
308
|
+
# @rbs (**__todo__ options) -> SymbolType
|
309
|
+
def _Symbol(**options)
|
310
|
+
require 'domainic/type/types/core/symbol_type'
|
311
|
+
Domainic::Type::SymbolType.new(**options)
|
312
|
+
end
|
313
|
+
alias _Interned _Symbol
|
314
|
+
|
315
|
+
# Creates a nilable SymbolType instance.
|
316
|
+
#
|
317
|
+
# @example
|
318
|
+
# type = _Symbol?
|
319
|
+
#
|
320
|
+
# @param options [Hash] additional configuration options
|
321
|
+
#
|
322
|
+
# @return [Domainic::Type::UnionType] the created type (Symbol or NilClass)
|
323
|
+
# @rbs (**__todo__ options) -> UnionType
|
324
|
+
def _Symbol?(**options)
|
325
|
+
symbol = _Symbol(**options)
|
326
|
+
_Nilable(symbol)
|
327
|
+
end
|
328
|
+
alias _Interned? _Symbol?
|
329
|
+
|
330
|
+
# Creates a UnionType instance.
|
331
|
+
#
|
332
|
+
# Allows combining multiple types into a single union type.
|
333
|
+
#
|
334
|
+
# @example
|
335
|
+
# type = _Union(String, Symbol)
|
336
|
+
#
|
337
|
+
# @param types [Array<Class, Module, Behavior>] the types included in the union
|
338
|
+
# @param options [Hash] additional configuration options
|
339
|
+
#
|
340
|
+
# @return [Domainic::Type::UnionType] the created type
|
341
|
+
# @rbs (*Class | Module | Behavior[untyped, untyped, untyped] types, **__todo__ options) -> UnionType
|
342
|
+
def _Union(*types, **options)
|
343
|
+
require 'domainic/type/types/specification/union_type'
|
344
|
+
Domainic::Type::UnionType.new(*types, **options)
|
345
|
+
end
|
346
|
+
alias _Either _Union
|
347
|
+
|
348
|
+
# Creates a VoidType instance.
|
349
|
+
#
|
350
|
+
# Represents an operation that returns no value.
|
351
|
+
#
|
352
|
+
# @example
|
353
|
+
# type = _Void
|
354
|
+
#
|
355
|
+
# @return [Domainic::Type::VoidType] the created type
|
356
|
+
# @rbs () -> VoidType
|
357
|
+
def _Void
|
358
|
+
require 'domainic/type/types/specification/void_type'
|
359
|
+
Domainic::Type::VoidType.new
|
360
|
+
end
|
361
|
+
# rubocop:enable Naming/MethodName
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'domainic/type/behavior'
|
4
|
+
require 'domainic/type/behavior/enumerable_behavior'
|
5
|
+
|
6
|
+
module Domainic
|
7
|
+
module Type
|
8
|
+
# A type for validating Array objects with flexible element and size constraints
|
9
|
+
#
|
10
|
+
# This class provides a comprehensive set of validations specifically designed for Array
|
11
|
+
# objects, including element type checking, value inclusion/exclusion, ordering, and all
|
12
|
+
# standard enumerable validations.
|
13
|
+
#
|
14
|
+
# Key features:
|
15
|
+
# - Element type validation
|
16
|
+
# - Element presence/absence validation
|
17
|
+
# - Uniqueness constraints
|
18
|
+
# - Order constraints
|
19
|
+
# - Size constraints (via EnumerableBehavior)
|
20
|
+
# - Standard collection validations (via EnumerableBehavior)
|
21
|
+
#
|
22
|
+
# @example Basic usage
|
23
|
+
# type = ArrayType.new
|
24
|
+
# type.of(String) # enforce element type
|
25
|
+
# type.containing(1, 2) # require specific elements
|
26
|
+
# type.having_size(3) # exact size constraint
|
27
|
+
# type.being_distinct # unique elements
|
28
|
+
#
|
29
|
+
# @example Complex constraints
|
30
|
+
# type = ArrayType.new
|
31
|
+
# type
|
32
|
+
# .of(Integer) # type constraints
|
33
|
+
# .being_ordered # must be sorted
|
34
|
+
# .having_size_between(2, 5) # size range
|
35
|
+
# .starting_with(1) # first element
|
36
|
+
#
|
37
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
38
|
+
# @since 0.1.0
|
39
|
+
class ArrayType
|
40
|
+
# @rbs! extend Behavior::ClassMethods
|
41
|
+
|
42
|
+
include Behavior
|
43
|
+
include Behavior::EnumerableBehavior
|
44
|
+
|
45
|
+
intrinsic :self, :type, Array, abort_on_failure: true, description: :not_described
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'domainic/type/behavior'
|
4
|
+
require 'domainic/type/behavior/numeric_behavior'
|
5
|
+
|
6
|
+
module Domainic
|
7
|
+
module Type
|
8
|
+
# A type for validating Float objects with extensive numeric validation capabilities.
|
9
|
+
#
|
10
|
+
# This class provides a comprehensive set of validations specifically designed for
|
11
|
+
# floating-point values, including basic type checking and all numeric validations
|
12
|
+
# like finiteness, polarity, and range constraints. It properly handles floating-point
|
13
|
+
# arithmetic by using appropriate tolerances in comparisons.
|
14
|
+
#
|
15
|
+
# @example Basic usage
|
16
|
+
# type = FloatType.new
|
17
|
+
# type.validate(3.14) # => true
|
18
|
+
# type.validate(42) # => false
|
19
|
+
# type.validate("3.14") # => false
|
20
|
+
#
|
21
|
+
# @example With numeric constraints
|
22
|
+
# type = FloatType.new
|
23
|
+
# type
|
24
|
+
# .being_positive
|
25
|
+
# .being_finite
|
26
|
+
# .being_less_than(10.0)
|
27
|
+
#
|
28
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
29
|
+
# @since 0.1.0
|
30
|
+
class FloatType
|
31
|
+
# @rbs! extend Behavior::ClassMethods
|
32
|
+
|
33
|
+
include Behavior
|
34
|
+
include Behavior::NumericBehavior
|
35
|
+
|
36
|
+
intrinsic :self, :type, Float, abort_on_failure: true, description: :not_described
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'domainic/type/behavior'
|
4
|
+
require 'domainic/type/behavior/enumerable_behavior'
|
5
|
+
|
6
|
+
module Domainic
|
7
|
+
module Type
|
8
|
+
# A type for validating Hash objects with flexible key and value constraints
|
9
|
+
#
|
10
|
+
# This class provides a comprehensive set of validations specifically designed
|
11
|
+
# for Hash objects, including key/value type checking, inclusion/exclusion of
|
12
|
+
# specific keys or values, and all standard enumerable validations.
|
13
|
+
#
|
14
|
+
# Key features:
|
15
|
+
# - Key type validation
|
16
|
+
# - Value type validation
|
17
|
+
# - Key presence/absence checking
|
18
|
+
# - Value presence/absence checking
|
19
|
+
# - Size constraints (via EnumerableBehavior)
|
20
|
+
# - Standard collection validations (via EnumerableBehavior)
|
21
|
+
#
|
22
|
+
# @example Basic usage
|
23
|
+
# type = HashType.new
|
24
|
+
# type.of(String => Integer) # enforce key/value types
|
25
|
+
# type.containing_keys('a', 'b') # require specific keys
|
26
|
+
# type.containing_values(1, 2) # require specific values
|
27
|
+
# type.having_size(2) # exact size constraint
|
28
|
+
#
|
29
|
+
# @example Complex constraints
|
30
|
+
# type = HashType.new
|
31
|
+
# type
|
32
|
+
# .of(Symbol => String) # type constraints
|
33
|
+
# .containing_keys(:name, :email) # required keys
|
34
|
+
# .excluding_values(nil, '') # no empty values
|
35
|
+
# .having_size_between(2, 5) # size range
|
36
|
+
#
|
37
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
38
|
+
# @since 0.1.0
|
39
|
+
class HashType
|
40
|
+
# @rbs! extend Behavior::ClassMethods
|
41
|
+
|
42
|
+
include Behavior
|
43
|
+
include Behavior::EnumerableBehavior
|
44
|
+
|
45
|
+
intrinsic :self, :type, Hash, abort_on_failure: true, description: :not_described
|
46
|
+
|
47
|
+
# Validate that the hash contains specific keys
|
48
|
+
#
|
49
|
+
# @example
|
50
|
+
# type.containing_keys(:name, :email)
|
51
|
+
# type.validate({ name: 'John', email: 'john@example.com' }) # => true
|
52
|
+
# type.validate({ name: 'John' }) # => false
|
53
|
+
#
|
54
|
+
# @param keys [Array<Object>] the keys that must be present
|
55
|
+
# @return [self] self for method chaining
|
56
|
+
# @rbs (*untyped keys) -> self
|
57
|
+
def containing_keys(*keys)
|
58
|
+
including = keys.map do |key|
|
59
|
+
@constraints.prepare :entries, :inclusion, key
|
60
|
+
end
|
61
|
+
constrain :keys, :and, including, concerning: :key_inclusion, description: 'keys'
|
62
|
+
end
|
63
|
+
alias including_keys containing_keys
|
64
|
+
|
65
|
+
# Validate that the hash contains specific values
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# type.containing_values('active', 'pending')
|
69
|
+
# type.validate({ status: 'active' }) # => true
|
70
|
+
# type.validate({ status: 'inactive' }) # => false
|
71
|
+
#
|
72
|
+
# @param values [Array<Object>] the values that must be present
|
73
|
+
# @return [self] self for method chaining
|
74
|
+
# @rbs (*untyped values) -> self
|
75
|
+
def containing_values(*values)
|
76
|
+
including = values.map do |value|
|
77
|
+
@constraints.prepare :entries, :inclusion, value
|
78
|
+
end
|
79
|
+
constrain :values, :and, including, concerning: :values_inclusion, description: 'values'
|
80
|
+
end
|
81
|
+
alias including_values containing_values
|
82
|
+
|
83
|
+
# Validate that the hash does not contain specific keys
|
84
|
+
#
|
85
|
+
# @example
|
86
|
+
# type.excluding_keys(:admin, :superuser)
|
87
|
+
# type.validate({ user: 'John' }) # => true
|
88
|
+
# type.validate({ admin: true }) # => false
|
89
|
+
#
|
90
|
+
# @param keys [Array<Object>] the keys that must not be present
|
91
|
+
# @return [self] self for method chaining
|
92
|
+
# @rbs (*untyped keys) -> self
|
93
|
+
def excluding_keys(*keys)
|
94
|
+
including = keys.map do |key|
|
95
|
+
@constraints.prepare :entries, :inclusion, key
|
96
|
+
end
|
97
|
+
constrain :keys, :nor, including, concerning: :key_exclusion, description: 'keys'
|
98
|
+
end
|
99
|
+
alias omitting_keys excluding_keys
|
100
|
+
|
101
|
+
# Validate that the hash does not contain specific values
|
102
|
+
#
|
103
|
+
# @example
|
104
|
+
# type.excluding_values(nil, '')
|
105
|
+
# type.validate({ name: 'John' }) # => true
|
106
|
+
# type.validate({ name: nil }) # => false
|
107
|
+
#
|
108
|
+
# @param values [Array<Object>] the values that must not be present
|
109
|
+
# @return [self] self for method chaining
|
110
|
+
# @rbs (*untyped values) -> self
|
111
|
+
def excluding_values(*values)
|
112
|
+
including = values.map do |value|
|
113
|
+
@constraints.prepare :entries, :inclusion, value
|
114
|
+
end
|
115
|
+
constrain :values, :nor, including, concerning: :values_exclusion, description: 'values'
|
116
|
+
end
|
117
|
+
alias omitting_values excluding_values
|
118
|
+
|
119
|
+
# Validate the hash to have the given key type and value type.
|
120
|
+
#
|
121
|
+
# @example
|
122
|
+
# type.of(String => Integer)
|
123
|
+
# type.validate({ 'a' => 1 }) # => true
|
124
|
+
# type.validate({ 1 => 'a' }) # => false
|
125
|
+
#
|
126
|
+
# @param key_to_value_type [Hash{Object => Object}] the key type and value type that the hash must have
|
127
|
+
#
|
128
|
+
# @raise [ArgumentError] if the key_to_value_type pair is not a Hash or does not have exactly one entry
|
129
|
+
# @return [self] self for method chaining
|
130
|
+
# @rbs (Hash[untyped, untyped] key_to_value_type) -> self
|
131
|
+
def of(key_to_value_type)
|
132
|
+
raise ArgumentError, 'The key_to_value_type pair must be a Hash' unless key_to_value_type.is_a?(Hash)
|
133
|
+
raise ArgumentError, 'The key_to_value_type pair must have exactly one entry' unless key_to_value_type.size == 1
|
134
|
+
|
135
|
+
key_type = @constraints.prepare :self, :type, key_to_value_type.keys.first
|
136
|
+
value_type = @constraints.prepare :self, :type, key_to_value_type.values.first
|
137
|
+
|
138
|
+
constrain :keys, :all, key_type, concerning: :key_type, description: 'having keys of'
|
139
|
+
constrain :values, :all, value_type, concerning: :value_type, description: 'having values of'
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'domainic/type/behavior'
|
4
|
+
require 'domainic/type/behavior/numeric_behavior'
|
5
|
+
|
6
|
+
module Domainic
|
7
|
+
module Type
|
8
|
+
# A type for validating Integer objects with extensive numeric validation capabilities.
|
9
|
+
#
|
10
|
+
# This class provides a comprehensive set of validations specifically designed for
|
11
|
+
# integer values, including basic type checking and all numeric validations like
|
12
|
+
# divisibility, parity, polarity, and range constraints.
|
13
|
+
#
|
14
|
+
# @example Basic usage
|
15
|
+
# type = IntegerType.new
|
16
|
+
# type.validate(42) # => true
|
17
|
+
# type.validate(3.14) # => false
|
18
|
+
# type.validate("42") # => false
|
19
|
+
#
|
20
|
+
# @example With numeric constraints
|
21
|
+
# type = IntegerType.new
|
22
|
+
# type
|
23
|
+
# .being_positive
|
24
|
+
# .being_even
|
25
|
+
# .being_less_than(100)
|
26
|
+
#
|
27
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
28
|
+
# @since 0.1.0
|
29
|
+
class IntegerType
|
30
|
+
# @rbs! extend Behavior::ClassMethods
|
31
|
+
|
32
|
+
include Behavior
|
33
|
+
include Behavior::NumericBehavior
|
34
|
+
|
35
|
+
intrinsic :self, :type, Integer, abort_on_failure: true, description: :not_described
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'domainic/type/behavior'
|
4
|
+
require 'domainic/type/behavior/string_behavior'
|
5
|
+
|
6
|
+
module Domainic
|
7
|
+
module Type
|
8
|
+
# A type for validating String objects with comprehensive string-specific constraints
|
9
|
+
#
|
10
|
+
# This type provides a complete set of string validation capabilities including case
|
11
|
+
# formatting, character set validation, pattern matching, and size constraints. It
|
12
|
+
# combines core string type checking with rich string-specific behaviors.
|
13
|
+
#
|
14
|
+
# Key features:
|
15
|
+
# - Basic string type validation
|
16
|
+
# - Case checking (upper, lower, mixed, title)
|
17
|
+
# - Character set validation (ASCII, alphanumeric, etc.)
|
18
|
+
# - Pattern matching with regular expressions
|
19
|
+
# - Size/length constraints
|
20
|
+
# - String content validation
|
21
|
+
#
|
22
|
+
# @example Basic usage
|
23
|
+
# type = StringType.new
|
24
|
+
# type.validate("hello") # => true
|
25
|
+
# type.validate(123) # => false
|
26
|
+
#
|
27
|
+
# @example Complex string validation
|
28
|
+
# type = StringType.new
|
29
|
+
# .being_ascii
|
30
|
+
# .being_alphanumeric
|
31
|
+
# .having_size_between(3, 20)
|
32
|
+
# .not_matching(/[^a-z0-9]/)
|
33
|
+
#
|
34
|
+
# @example Case validation
|
35
|
+
# type = StringType.new
|
36
|
+
# .being_titlecase
|
37
|
+
# .matching(/^[A-Z]/)
|
38
|
+
# .having_minimum_size(2)
|
39
|
+
#
|
40
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
41
|
+
# @since 0.1.0
|
42
|
+
class StringType
|
43
|
+
# @rbs! extend Behavior::ClassMethods
|
44
|
+
|
45
|
+
include Behavior
|
46
|
+
include Behavior::StringBehavior
|
47
|
+
|
48
|
+
intrinsic :self, :type, String, abort_on_failure: true, description: :not_described
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|