domainic-type 0.1.0.alpha.3.2.0 → 0.1.0.alpha.3.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.
@@ -4,12 +4,12 @@ module Domainic
4
4
  module Type
5
5
  # @rbs!
6
6
  # type accessor = :abs | :begin | :chars | :class | :count | :end | :entries | :first | :keys | :last | :length |
7
- # :self | :size | :values
7
+ # :real | :self | :size | :values
8
8
 
9
9
  # A list of valid access methods that can be used to retrieve values for constraint validation.
10
10
  # These methods represent common Ruby interfaces for accessing collection sizes, ranges, and values.
11
11
  #
12
- # - :abs - For absolute values
12
+ # - :abs, :real - For absolute values
13
13
  # - :begin, :end - For Range-like objects
14
14
  # - :class - For type checking
15
15
  # - :count, :length, :size - For measuring collections
@@ -27,6 +27,7 @@ module Domainic
27
27
  entries
28
28
  chars
29
29
  abs
30
+ real
30
31
  count
31
32
  size
32
33
  length
@@ -28,13 +28,89 @@ module Domainic
28
28
  # @author {https://aaronmallen.me Aaron Allen}
29
29
  # @since 0.1.0
30
30
  module DateTimeBehavior
31
+ # The supported date/time patterns for parsing date/time strings
32
+ #
33
+ # @note This list is ordered from most specific to least specific to ensure that the most specific patterns are
34
+ # tried first. This is important because some patterns are more lenient than others and may match a wider range
35
+ # of input strings.
36
+ #
37
+ # @return [Array<String>] the supported date/time patterns
38
+ DATETIME_PATTERNS = [
39
+ # ISO 8601 variants (most specific first)
40
+ '%Y-%m-%dT%H:%M:%S.%N%:z', # 2024-01-01T12:00:00.000+00:00
41
+ '%Y-%m-%dT%H:%M:%S%:z', # 2024-01-01T12:00:00+00:00
42
+ '%Y-%m-%dT%H:%M:%S.%N', # 2024-01-01T12:00:00.000
43
+ '%Y-%m-%dT%H:%M:%S', # 2024-01-01T12:00:00
44
+ '%Y%m%dT%H%M%S%z', # 20240101T120000+0000 (basic format)
45
+
46
+ # RFC formats
47
+ '%a, %d %b %Y %H:%M:%S %z', # Thu, 31 Jan 2024 13:30:00 +0000
48
+ '%d %b %Y %H:%M:%S %z', # 31 Jan 2024 13:30:00 +0000
49
+
50
+ # Common datetime formats with timezone
51
+ '%Y-%m-%d %H:%M:%S %z', # 2024-01-01 12:00:00 +0000
52
+ '%d/%m/%Y %H:%M:%S %z', # 31/01/2024 12:00:00 +0000
53
+
54
+ # Full date + time formats (24h)
55
+ '%Y-%m-%d %H:%M:%S', # 2024-01-01 12:00:00
56
+ '%Y-%m-%d %H:%M', # 2024-01-01 12:00
57
+ '%d/%m/%Y %H:%M:%S', # 31/01/2024 12:00:00
58
+ '%d/%m/%Y %H:%M', # 31/01/2024 12:00
59
+ '%d-%m-%Y %H:%M:%S', # 31-01-2024 12:00:00
60
+ '%d-%m-%Y %H:%M', # 31-01-2024 12:00
61
+ '%Y/%m/%d %H:%M:%S', # 2024/01/31 12:00:00
62
+ '%Y/%m/%d %H:%M', # 2024/01/31 12:00
63
+
64
+ # Full date + time formats (12h)
65
+ '%Y-%m-%d %I:%M:%S %p', # 2024-01-01 01:30:00 PM
66
+ '%Y-%m-%d %I:%M %p', # 2024-01-01 01:30 PM
67
+ '%d/%m/%Y %I:%M:%S %p', # 31/01/2024 01:30:00 PM
68
+ '%d/%m/%Y %I:%M %p', # 31/01/2024 01:30 PM
69
+
70
+ # Full month name formats
71
+ '%B %d, %Y %H:%M:%S', # January 31, 2024 12:00:00
72
+ '%B %d, %Y %H:%M', # January 31, 2024 12:00
73
+ '%d %B %Y %H:%M:%S', # 31 January 2024 12:00:00
74
+ '%d %B %Y %H:%M', # 31 January 2024 12:00
75
+
76
+ # Abbreviated month name formats
77
+ '%b %d, %Y %H:%M:%S', # Jan 31, 2024 12:00:00
78
+ '%b %d, %Y %H:%M', # Jan 31, 2024 12:00
79
+ '%d %b %Y %H:%M:%S', # 31 Jan 2024 12:00:00
80
+ '%d %b %Y %H:%M', # 31 Jan 2024 12:00
81
+
82
+ # Date-only formats (in order of specificity)
83
+ '%Y-%m-%d', # 2024-01-31
84
+ '%Y%m%d', # 20240131
85
+ '%B %d, %Y', # January 31, 2024
86
+ '%d %B %Y', # 31 January 2024
87
+ '%b %d, %Y', # Jan 31, 2024
88
+ '%d %b %Y', # 31 Jan 2024
89
+ '%d/%m/%Y', # 31/01/2024
90
+ '%d-%m-%Y', # 31-01-2024
91
+ '%Y/%m/%d', # 2024/01/31
92
+ '%m/%d/%Y' # 01/31/2024 (US format - last to avoid ambiguity)
93
+ ].freeze #: Array[String]
94
+
95
+ # Coerce a value to a Date, DateTime, or Time object
96
+ #
97
+ # @return [Proc] a lambda that coerces a value to a Date, DateTime, or Time object
31
98
  TO_DATETIME_COERCER = lambda { |value|
32
- if [Date, DateTime, Time].any? { |type| value.is_a?(type) }
99
+ case value
100
+ when Date, DateTime, Time
33
101
  value
102
+ when Integer
103
+ Time.at(value).to_datetime
104
+ when String
105
+ DATETIME_PATTERNS.each do |pattern|
106
+ return DateTime.strptime(value, pattern)
107
+ rescue ArgumentError
108
+ next
109
+ end
34
110
  else
35
- DateTime.parse(value.to_s)
111
+ DateTime.parse(value) # Fallback to Ruby's built-in parser and allow it to raise.
36
112
  end
37
- } #: Proc
113
+ } #: ^(Date | DateTime | Integer | String | Time value) -> (Date | DateTime | Time)
38
114
 
39
115
  class << self
40
116
  private
@@ -44,39 +120,39 @@ module Domainic
44
120
  # @note this in my opinion is better than polluting the namespace of the including class even with a private
45
121
  # method. This way, the method is only available within the module itself. See {#being_between}.
46
122
  #
47
- # @param after [Date, DateTime, String, Time, nil] minimum size value from positional args
48
- # @param before [Date, DateTime, String, Time, nil] maximum size value from positional args
123
+ # @param after [Date, DateTime, Integer, String, Time, nil] minimum size value from positional args
124
+ # @param before [Date, DateTime, Integer, String, Time, nil] maximum size value from positional args
49
125
  # @param options [Hash] keyword arguments containing after/before values
50
126
  #
51
127
  # @raise [ArgumentError] if minimum or maximum value can't be determined
52
- # @return [Array<Date, DateTime, String, Time, nil>] parsed [after, before] values
128
+ # @return [Array<Date, DateTime, Integer, String, Time, nil>] parsed [after, before] values
53
129
  # @rbs (
54
- # (Date | DateTime | String | Time)? after,
55
- # (Date | DateTime | String | Time)? before,
56
- # Hash[Symbol, (Date | DateTime | String | Time)?] options
57
- # ) -> Array[(Date | DateTime | String | Time)?]
130
+ # (Date | DateTime | Integer | String | Time)? after,
131
+ # (Date | DateTime | Integer | String | Time)? before,
132
+ # Hash[Symbol, (Date | DateTime | Integer | String | Time)?] options
133
+ # ) -> Array[(Date | DateTime | Integer | String | Time)?]
58
134
  def parse_being_between_arguments!(after, before, options)
59
135
  after ||= options[:after]
60
136
  before ||= options[:before]
61
137
  raise_being_between_argument_error!(caller, after, before, options) if after.nil? || before.nil?
62
138
 
63
- [after, before] #: Array[(Date | DateTime | String | Time)?]
139
+ [after, before] #: Array[(Date | DateTime | Integer | String | Time)?]
64
140
  end
65
141
 
66
142
  # Raise appropriate ArgumentError for being_between
67
143
  #
68
144
  # @param original_caller [Array<String>] caller stack for error
69
- # @param after [Date, DateTime, String, Time, nil] after value from positional args
70
- # @param before [Date, DateTime, String, Time, nil] before value from positional args
145
+ # @param after [Date, DateTime, Integer, String, Time, nil] after value from positional args
146
+ # @param before [Date, DateTime, Integer, String, Time, nil] before value from positional args
71
147
  # @param options [Hash] keyword arguments containing after/before values
72
148
  #
73
149
  # @raise [ArgumentError] with appropriate message
74
150
  # @return [void]
75
151
  # @rbs (
76
152
  # Array[String] original_caller,
77
- # (Date | DateTime | String | Time)? after,
78
- # (Date | DateTime | String | Time)? before,
79
- # Hash[Symbol, (Date | DateTime | String | Time)?] options
153
+ # (Date | DateTime | Integer | String | Time)? after,
154
+ # (Date | DateTime | Integer | String | Time)? before,
155
+ # Hash[Symbol, (Date | DateTime | Integer | String | Time)?] options
80
156
  # ) -> void
81
157
  def raise_being_between_argument_error!(original_caller, after, before, options)
82
158
  message = if options.empty?
@@ -93,66 +169,70 @@ module Domainic
93
169
 
94
170
  # Constrain the value to be chronologically after a given date/time
95
171
  #
96
- # @param other [Date, DateTime, String, Time] the date/time to compare against
172
+ # @param other [Date, DateTime, Integer, String, Time] the date/time to compare against
97
173
  # @return [self] self for method chaining
98
- # @rbs (Date | DateTime | String | Time other) -> Behavior
174
+ # @rbs (Date | DateTime | Integer | String | Time other) -> Behavior
99
175
  def being_after(other)
100
176
  # @type self: Object & Behavior
101
- constrain :self, :range, { minimum: other },
177
+ constrain :self, :range, { minimum: TO_DATETIME_COERCER.call(other) },
102
178
  coerce_with: TO_DATETIME_COERCER, description: 'being', inclusive: false
103
179
  end
104
180
  alias after being_after
105
181
 
106
182
  # Constrain the value to be chronologically before a given date/time
107
183
  #
108
- # @param other [Date, DateTime, String, Time] the date/time to compare against
184
+ # @param other [Date, DateTime, Integer, String, Time] the date/time to compare against
109
185
  # @return [self] self for method chaining
110
- # @rbs (Date | DateTime | String | Time other) -> Behavior
186
+ # @rbs (Date | DateTime | Integer | String | Time other) -> Behavior
111
187
  def being_before(other)
112
188
  # @type self: Object & Behavior
113
- constrain :self, :range, { maximum: other },
189
+ constrain :self, :range, { maximum: TO_DATETIME_COERCER.call(other) },
114
190
  coerce_with: TO_DATETIME_COERCER, description: 'being', inclusive: false
115
191
  end
116
192
  alias before being_before
117
193
 
118
194
  # Constrain the value to be chronologically between two date/times
119
195
  #
120
- # @param after [Date, DateTime, String, Time] the earliest allowed date/time
121
- # @param before [Date, DateTime, String, Time] the latest allowed date/time
196
+ # @param after [Date, DateTime, Integer, String, Time] the earliest allowed date/time
197
+ # @param before [Date, DateTime, Integer, String, Time] the latest allowed date/time
122
198
  # @param options [Hash] alternative way to specify after/before via keywords
123
- # @option options [Date, DateTime, String, Time] :after earliest allowed date/time
124
- # @option options [Date, DateTime, String, Time] :before latest allowed date/time
199
+ # @option options [Date, DateTime, Integer, String, Time] :after earliest allowed date/time
200
+ # @option options [Date, DateTime, Integer, String, Time] :before latest allowed date/time
125
201
  # @return [self] self for method chaining
126
- # @rbs (Date | DateTime | String | Time after, Date | DateTime | String | Time before) -> Behavior
202
+ # @rbs (
203
+ # Date | DateTime | Integer | String | Time after,
204
+ # Date | DateTime | Integer | String | Time before
205
+ # ) -> Behavior
127
206
  def being_between(after = nil, before = nil, **options)
128
207
  # @type self: Object & Behavior
129
208
  after, before =
130
209
  DateTimeBehavior.send(:parse_being_between_arguments!, after, before, options.transform_keys(&:to_sym))
131
- constrain :self, :range, { minimum: after, maximum: before },
210
+ constrain :self, :range,
211
+ { minimum: TO_DATETIME_COERCER.call(after), maximum: TO_DATETIME_COERCER.call(before) },
132
212
  coerce_with: TO_DATETIME_COERCER, description: 'being', inclusive: false
133
213
  end
134
214
  alias between being_between
135
215
 
136
216
  # Constrain the value to be exactly equal to a given date/time
137
217
  #
138
- # @param other [Date, DateTime, String, Time] the date/time to compare against
218
+ # @param other [Date, DateTime, Integer, String, Time] the date/time to compare against
139
219
  # @return [self] self for method chaining
140
- # @rbs (Date | DateTime | String | Time other) -> Behavior
220
+ # @rbs (Date | DateTime | Integer | String | Time other) -> Behavior
141
221
  def being_equal_to(other)
142
222
  # @type self: Object & Behavior
143
- constrain :self, :equality, other,
223
+ constrain :self, :equality, TO_DATETIME_COERCER.call(other),
144
224
  coerce_with: TO_DATETIME_COERCER, description: 'being'
145
225
  end
146
226
  alias at being_equal_to
147
227
 
148
228
  # Constrain the value to be chronologically on or after a given date/time
149
229
  #
150
- # @param other [Date, DateTime, String, Time] the date/time to compare against
230
+ # @param other [Date, DateTime, Integer, String, Time] the date/time to compare against
151
231
  # @return [self] self for method chaining
152
- # @rbs (Date | DateTime | String | Time other) -> Behavior
232
+ # @rbs (Date | DateTime | Integer | String | Time other) -> Behavior
153
233
  def being_on_or_after(other)
154
234
  # @type self: Object & Behavior
155
- constrain :self, :range, { minimum: other },
235
+ constrain :self, :range, { minimum: TO_DATETIME_COERCER.call(other) },
156
236
  coerce_with: TO_DATETIME_COERCER, description: 'being'
157
237
  end
158
238
  alias at_or_after being_on_or_after
@@ -161,12 +241,12 @@ module Domainic
161
241
 
162
242
  # Constrain the value to be chronologically on or before a given date/time
163
243
  #
164
- # @param other [Date, DateTime, String, Time] the date/time to compare against
244
+ # @param other [Date, DateTime, Integer, String, Time] the date/time to compare against
165
245
  # @return [self] self for method chaining
166
- # @rbs (Date | DateTime | String | Time other) -> Behavior
246
+ # @rbs (Date | DateTime | Integer | String | Time other) -> Behavior
167
247
  def being_on_or_before(other)
168
248
  # @type self: Object & Behavior
169
- constrain :self, :range, { maximum: other },
249
+ constrain :self, :range, { maximum: TO_DATETIME_COERCER.call(other) },
170
250
  coerce_with: TO_DATETIME_COERCER, description: 'being'
171
251
  end
172
252
  alias at_or_before being_on_or_before
@@ -78,6 +78,12 @@ types:
78
78
  anything:
79
79
  constant: Domainic::Type::AnythingType
80
80
  require_path: domainic/type/types/specification/anything_type
81
+ big_decimal:
82
+ constant: Domainic::Type::BigDecimalType
83
+ require_path: domainic/type/types/core_extended/big_decimal_type
84
+ complex:
85
+ constant: Domainic::Type::ComplexType
86
+ require_path: domainic/type/types/core/complex_type
81
87
  cuid:
82
88
  constant: Domainic::Type::CUIDType
83
89
  require_path: domainic/type/types/identifier/cuid_type
@@ -87,6 +93,9 @@ types:
87
93
  date_time:
88
94
  constant: Domainic::Type::DateTimeType
89
95
  require_path: domainic/type/types/datetime/date_time_type
96
+ date_time_string:
97
+ constant: Domainic::Type::DateTimeStringType
98
+ require_path: domainic/type/types/datetime/date_time_string_type
90
99
  duck:
91
100
  constant: Domainic::Type::DuckType
92
101
  require_path: domainic/type/types/specification/duck_type
@@ -111,6 +120,15 @@ types:
111
120
  integer:
112
121
  constant: Domainic::Type::IntegerType
113
122
  require_path: domainic/type/types/core/integer_type
123
+ range:
124
+ constant: Domainic::Type::RangeType
125
+ require_path: domainic/type/types/core/range_type
126
+ rational:
127
+ constant: Domainic::Type::RationalType
128
+ require_path: domainic/type/types/core/rational_type
129
+ set:
130
+ constant: Domainic::Type::SetType
131
+ require_path: domainic/type/types/core_extended/set_type
114
132
  string:
115
133
  constant: Domainic::Type::StringType
116
134
  require_path: domainic/type/types/core/string_type
@@ -120,6 +138,9 @@ types:
120
138
  time:
121
139
  constant: Domainic::Type::TimeType
122
140
  require_path: domainic/type/types/datetime/time_type
141
+ timestamp:
142
+ constant: Domainic::Type::TimestampType
143
+ require_path: domainic/type/types/datetime/timestamp_type
123
144
  union:
124
145
  constant: Domainic::Type::UnionType
125
146
  require_path: domainic/type/types/specification/union_type
@@ -77,6 +77,36 @@ module Domainic
77
77
  end
78
78
  alias _List? _Array?
79
79
 
80
+ # Creates a BigDecimalType instance.
81
+ #
82
+ # @example
83
+ # type = _BigDecimal
84
+ # type.validate(BigDecimal('123.45')) # => true
85
+ #
86
+ # @param options [Hash] additional configuration options
87
+ #
88
+ # @return [Domainic::Type::BigDecimalType] the created type
89
+ # @rbs (**__todo__ options) -> BigDecimalType
90
+ def _BigDecimal(**options)
91
+ require 'domainic/type/types/core_extended/big_decimal_type'
92
+ Domainic::Type::BigDecimalType.new(**options)
93
+ end
94
+
95
+ # Creates a nilable BigDecimalType instance.
96
+ #
97
+ # @example
98
+ # type = _BigDecimal?
99
+ # type.validate(BigDecimal('123.45')) # => true
100
+ # type.validate(nil) # => true
101
+ #
102
+ # @param options [Hash] additional configuration options
103
+ #
104
+ # @return [Domainic::Type::UnionType] the created type (BigDecimal or NilClass)
105
+ # @rbs (**__todo__ options) -> UnionType
106
+ def _BigDecimal?(**options)
107
+ _Nilable(_BigDecimal(**options))
108
+ end
109
+
80
110
  # Creates a Boolean type.
81
111
  #
82
112
  # Represents a union of TrueClass and FalseClass.
@@ -133,6 +163,35 @@ module Domainic
133
163
  end
134
164
  alias _Cuid? _CUID?
135
165
 
166
+ # Creates a ComplexType instance.
167
+ #
168
+ # @example
169
+ # type = _Complex
170
+ # type.validate(Complex(1, 2)) # => true
171
+ #
172
+ # @param options [Hash] additional configuration options
173
+ #
174
+ # @return [Domainic::Type::ComplexType] the created type
175
+ # @rbs (**__todo__ options) -> ComplexType
176
+ def _Complex(**options)
177
+ require 'domainic/type/types/core/complex_type'
178
+ Domainic::Type::ComplexType.new(**options)
179
+ end
180
+
181
+ # Creates a nilable ComplexType instance.
182
+ #
183
+ # @example
184
+ # type = _Complex?
185
+ # type.validate(Complex(1, 2)) # => true
186
+ #
187
+ # @param options [Hash] additional configuration options
188
+ #
189
+ # @return [Domainic::Type::UnionType] the created type (Complex or NilClass)
190
+ # @rbs (**__todo__ options) -> UnionType
191
+ def _Complex?(**options)
192
+ _Nilable(_Complex(**options))
193
+ end
194
+
136
195
  # Creates a DateType instance.
137
196
  #
138
197
  # DateType restricts values to valid `Date` objects.
@@ -195,6 +254,39 @@ module Domainic
195
254
  _Nilable(_DateTime(**options))
196
255
  end
197
256
 
257
+ # Creates a DateTimeStringType instance.
258
+ #
259
+ # DateTimeStringType restricts values to valid date-time strings.
260
+ #
261
+ # @example
262
+ # type = _DateTimeString
263
+ # type.validate('2024-01-01T12:00:00Z') # => true
264
+ #
265
+ # @param options [Hash] additional configuration options
266
+ #
267
+ # @return [Domainic::Type::DateTimeStringType] the created type
268
+ # @rbs (**__todo__ options) -> DateTimeStringType
269
+ def _DateTimeString(**options)
270
+ require 'domainic/type/types/datetime/date_time_string_type'
271
+ Domainic::Type::DateTimeStringType.new(**options)
272
+ end
273
+ alias _DateString _DateTimeString
274
+
275
+ # Creates a nilable DateTimeStringType instance.
276
+ #
277
+ # @example
278
+ # _DateTimeString? === '2024-01-01T12:00:00Z' # => true
279
+ # _DateTimeString? === nil # => true
280
+ #
281
+ # @param options [Hash] additional configuration options
282
+ #
283
+ # @return [Domainic::Type::UnionType] the created type (DateTimeStringType or NilClass)
284
+ # @rbs (**__todo__ options) -> UnionType
285
+ def _DateTimeString?(**options)
286
+ _Nilable(_DateTimeString(**options))
287
+ end
288
+ alias _DateString? _DateTimeString?
289
+
198
290
  # Creates a DuckType instance.
199
291
  #
200
292
  # DuckType allows specifying behavior based on method availability.
@@ -477,6 +569,95 @@ module Domainic
477
569
  end
478
570
  alias _Nullable _Nilable
479
571
 
572
+ # Creates a RangeType instance.
573
+ #
574
+ # @example
575
+ # type = _Range
576
+ # type.validate(1..10) # => true
577
+ #
578
+ # @param options [Hash] additional configuration options
579
+ #
580
+ # @return [Domainic::Type::RangeType] the created type
581
+ # @rbs (**__todo__ options) -> RangeType
582
+ def _Range(**options)
583
+ require 'domainic/type/types/core/range_type'
584
+ Domainic::Type::RangeType.new(**options)
585
+ end
586
+
587
+ # Creates a nilable RangeType instance.
588
+ #
589
+ # @example
590
+ # type = _Range?
591
+ # type.validate(1..10) # => true
592
+ #
593
+ # @param options [Hash] additional configuration options
594
+ #
595
+ # @return [Domainic::Type::UnionType] the created type (Range or NilClass)
596
+ # @rbs (**__todo__ options) -> UnionType
597
+ def _Range?(**options)
598
+ _Nilable(_Range(**options))
599
+ end
600
+
601
+ # Creates a RationalType instance.
602
+ #
603
+ # @example
604
+ # type = _Rational
605
+ # type.validate(Rational(1, 2)) # => true
606
+ #
607
+ # @param options [Hash] additional configuration options
608
+ #
609
+ # @return [Domainic::Type::RationalType] the created type
610
+ # @rbs (**__todo__ options) -> RationalType
611
+ def _Rational(**options)
612
+ require 'domainic/type/types/core/rational_type'
613
+ Domainic::Type::RationalType.new(**options)
614
+ end
615
+
616
+ # Creates a nilable RationalType instance.
617
+ #
618
+ # @example
619
+ # type = _Rational?
620
+ # type.validate(Rational(1, 2)) # => true
621
+ # type.validate(nil) # => true
622
+ #
623
+ # @param options [Hash] additional configuration options
624
+ #
625
+ # @return [Domainic::Type::UnionType] the created type (Rational or NilClass)
626
+ # @rbs (**__todo__ options) -> UnionType
627
+ def _Rational?(**options)
628
+ _Nilable(_Rational(**options))
629
+ end
630
+
631
+ # Creates a SetType instance.
632
+ #
633
+ # @example
634
+ # type = _Set
635
+ # type.validate(Set[1, 2, 3]) # => true
636
+ #
637
+ # @param options [Hash] additional configuration options
638
+ #
639
+ # @return [Domainic::Type::SetType] the created type
640
+ # @rbs (**__todo__ options) -> SetType
641
+ def _Set(**options)
642
+ require 'domainic/type/types/core_extended/set_type'
643
+ Domainic::Type::SetType.new(**options)
644
+ end
645
+
646
+ # Creates a nilable SetType instance.
647
+ #
648
+ # @example
649
+ # type = _Set?
650
+ # type.validate(Set[1, 2, 3]) # => true
651
+ # type.validate(nil) # => true
652
+ #
653
+ # @param options [Hash] additional configuration options
654
+ #
655
+ # @return [Domainic::Type::UnionType] the created type (Set or NilClass)
656
+ # @rbs (**__todo__ options) -> UnionType
657
+ def _Set?(**options)
658
+ _Nilable(_Set(**options))
659
+ end
660
+
480
661
  # Creates a StringType instance.
481
662
  #
482
663
  # @example
@@ -568,6 +749,37 @@ module Domainic
568
749
  _Nilable(_Time(**options))
569
750
  end
570
751
 
752
+ # Creates a TimestampType instance.
753
+ #
754
+ # TimestampType restricts values to valid timestamps.
755
+ #
756
+ # @example
757
+ # type = _Timestamp
758
+ # type.validate(1640995200) # => true
759
+ #
760
+ # @param options [Hash] additional configuration options
761
+ #
762
+ # @return [Domainic::Type::TimestampType] the created type
763
+ # @rbs (**__todo__ options) -> TimestampType
764
+ def _Timestamp(**options)
765
+ require 'domainic/type/types/datetime/timestamp_type'
766
+ Domainic::Type::TimestampType.new(**options)
767
+ end
768
+
769
+ # Creates a nilable TimestampType instance.
770
+ #
771
+ # @example
772
+ # _Timestamp? === 1640995200 # => true
773
+ # _Timestamp? === nil # => true
774
+ #
775
+ # @param options [Hash] additional configuration options
776
+ #
777
+ # @return [Domainic::Type::UnionType] the created type (TimestampType or NilClass)
778
+ # @rbs (**__todo__ options) -> UnionType
779
+ def _Timestamp?(**options)
780
+ _Nilable(_Timestamp(**options))
781
+ end
782
+
571
783
  # Creates a URIType instance.
572
784
  #
573
785
  # URIType restricts values to valid URIs.