domainic-type 0.1.0.alpha.3.2.0 → 0.1.0.alpha.3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +11 -0
- data/README.md +66 -10
- data/docs/USAGE.md +787 -0
- data/lib/domainic/type/accessors.rb +3 -2
- data/lib/domainic/type/behavior/date_time_behavior.rb +121 -37
- data/lib/domainic/type/behavior.rb +16 -0
- data/lib/domainic/type/config/registry.yml +24 -0
- data/lib/domainic/type/constraint/constraints/nor_constraint.rb +1 -1
- data/lib/domainic/type/constraint/constraints/predicate_constraint.rb +76 -0
- data/lib/domainic/type/definitions.rb +212 -0
- data/lib/domainic/type/types/core/complex_type.rb +122 -0
- data/lib/domainic/type/types/core/range_type.rb +47 -0
- data/lib/domainic/type/types/core/rational_type.rb +38 -0
- data/lib/domainic/type/types/core_extended/big_decimal_type.rb +34 -0
- data/lib/domainic/type/types/core_extended/set_type.rb +34 -0
- data/lib/domainic/type/types/datetime/date_time_string_type.rb +156 -0
- data/lib/domainic/type/types/datetime/timestamp_type.rb +50 -0
- data/sig/domainic/type/accessors.rbs +2 -2
- data/sig/domainic/type/behavior/date_time_behavior.rbs +35 -23
- data/sig/domainic/type/behavior.rbs +9 -0
- data/sig/domainic/type/constraint/constraints/predicate_constraint.rbs +56 -0
- data/sig/domainic/type/definitions.rbs +165 -0
- data/sig/domainic/type/types/core/complex_type.rbs +96 -0
- data/sig/domainic/type/types/core/range_type.rbs +41 -0
- data/sig/domainic/type/types/core/rational_type.rbs +32 -0
- data/sig/domainic/type/types/core_extended/big_decimal_type.rbs +27 -0
- data/sig/domainic/type/types/core_extended/set_type.rbs +27 -0
- data/sig/domainic/type/types/datetime/date_time_string_type.rbs +124 -0
- data/sig/domainic/type/types/datetime/timestamp_type.rbs +44 -0
- metadata +25 -6
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'domainic/type/behavior'
|
4
|
+
require 'domainic/type/behavior/date_time_behavior'
|
5
|
+
|
6
|
+
module Domainic
|
7
|
+
module Type
|
8
|
+
# A type for validating Unix timestamps (seconds since the Unix epoch).
|
9
|
+
#
|
10
|
+
# This type ensures the value is an `Integer` representing a valid Unix
|
11
|
+
# timestamp. It integrates with `DateTimeBehavior` to provide a rich set of
|
12
|
+
# validation capabilities, including chronological constraints and range checks.
|
13
|
+
#
|
14
|
+
# Key features:
|
15
|
+
# - Ensures the value is an `Integer` representing a Unix timestamp.
|
16
|
+
# - Supports chronological relationship constraints (e.g., before, after).
|
17
|
+
# - Provides range, equality, and nilable checks.
|
18
|
+
#
|
19
|
+
# @example Basic usage
|
20
|
+
# type = TimestampType.new
|
21
|
+
# type.validate(Time.now.to_i) # => true
|
22
|
+
# type.validate(Date.today.to_time.to_i) # => true
|
23
|
+
# type.validate('invalid') # => false
|
24
|
+
#
|
25
|
+
# @example Range validation
|
26
|
+
# type = TimestampType.new
|
27
|
+
# .being_between(Time.now.to_i, (Time.now + 3600).to_i)
|
28
|
+
# type.validate((Time.now + 1800).to_i) # => true
|
29
|
+
# type.validate((Time.now + 7200).to_i) # => false
|
30
|
+
#
|
31
|
+
# @example Historical timestamps
|
32
|
+
# type = TimestampType.new
|
33
|
+
# type.validate(-1234567890) # => true (date before 1970-01-01)
|
34
|
+
#
|
35
|
+
# @example Nilable timestamp
|
36
|
+
# nilable_type = _Nilable(TimestampType.new)
|
37
|
+
# nilable_type.validate(nil) # => true
|
38
|
+
#
|
39
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
40
|
+
# @since 0.1.0
|
41
|
+
class TimestampType
|
42
|
+
# @rbs! extend Behavior::ClassMethods
|
43
|
+
|
44
|
+
include Behavior
|
45
|
+
include Behavior::DateTimeBehavior
|
46
|
+
|
47
|
+
intrinsically_constrain :self, :type, Integer, abort_on_failure: true, description: :not_described
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Domainic
|
2
2
|
module Type
|
3
|
-
type accessor = :abs | :begin | :chars | :class | :count | :end | :entries | :first | :keys | :last | :length | :self | :size | :values
|
3
|
+
type accessor = :abs | :begin | :chars | :class | :count | :end | :entries | :first | :keys | :last | :length | :real | :self | :size | :values
|
4
4
|
|
5
5
|
# A list of valid access methods that can be used to retrieve values for constraint validation.
|
6
6
|
# These methods represent common Ruby interfaces for accessing collection sizes, ranges, and values.
|
7
7
|
#
|
8
|
-
# - :abs
|
8
|
+
# - :abs, :real - For absolute values
|
9
9
|
# - :begin, :end - For Range-like objects
|
10
10
|
# - :class - For type checking
|
11
11
|
# - :count, :length, :size - For measuring collections
|
@@ -24,73 +24,85 @@ module Domainic
|
|
24
24
|
# @author {https://aaronmallen.me Aaron Allen}
|
25
25
|
# @since 0.1.0
|
26
26
|
module DateTimeBehavior
|
27
|
-
|
27
|
+
# The supported date/time patterns for parsing date/time strings
|
28
|
+
#
|
29
|
+
# @note This list is ordered from most specific to least specific to ensure that the most specific patterns are
|
30
|
+
# tried first. This is important because some patterns are more lenient than others and may match a wider range
|
31
|
+
# of input strings.
|
32
|
+
#
|
33
|
+
# @return [Array<String>] the supported date/time patterns
|
34
|
+
DATETIME_PATTERNS: Array[String]
|
35
|
+
|
36
|
+
# Coerce a value to a Date, DateTime, or Time object
|
37
|
+
#
|
38
|
+
# @return [Proc] a lambda that coerces a value to a Date, DateTime, or Time object
|
39
|
+
TO_DATETIME_COERCER: ^(Date | DateTime | Integer | String | Time value) -> (Date | DateTime | Time)
|
28
40
|
|
29
41
|
# Parse arguments for being_between
|
30
42
|
#
|
31
43
|
# @note this in my opinion is better than polluting the namespace of the including class even with a private
|
32
44
|
# method. This way, the method is only available within the module itself. See {#being_between}.
|
33
45
|
#
|
34
|
-
# @param after [Date, DateTime, String, Time, nil] minimum size value from positional args
|
35
|
-
# @param before [Date, DateTime, String, Time, nil] maximum size value from positional args
|
46
|
+
# @param after [Date, DateTime, Integer, String, Time, nil] minimum size value from positional args
|
47
|
+
# @param before [Date, DateTime, Integer, String, Time, nil] maximum size value from positional args
|
36
48
|
# @param options [Hash] keyword arguments containing after/before values
|
37
49
|
#
|
38
50
|
# @raise [ArgumentError] if minimum or maximum value can't be determined
|
39
|
-
# @return [Array<Date, DateTime, String, Time, nil>] parsed [after, before] values
|
40
|
-
private def self.parse_being_between_arguments!: ((Date | DateTime | String | Time)? after, (Date | DateTime | String | Time)? before, Hash[Symbol, (Date | DateTime | String | Time)?] options) -> Array[(Date | DateTime | String | Time)?]
|
51
|
+
# @return [Array<Date, DateTime, Integer, String, Time, nil>] parsed [after, before] values
|
52
|
+
private def self.parse_being_between_arguments!: ((Date | DateTime | Integer | String | Time)? after, (Date | DateTime | Integer | String | Time)? before, Hash[Symbol, (Date | DateTime | Integer | String | Time)?] options) -> Array[(Date | DateTime | Integer | String | Time)?]
|
41
53
|
|
42
54
|
# Raise appropriate ArgumentError for being_between
|
43
55
|
#
|
44
56
|
# @param original_caller [Array<String>] caller stack for error
|
45
|
-
# @param after [Date, DateTime, String, Time, nil] after value from positional args
|
46
|
-
# @param before [Date, DateTime, String, Time, nil] before value from positional args
|
57
|
+
# @param after [Date, DateTime, Integer, String, Time, nil] after value from positional args
|
58
|
+
# @param before [Date, DateTime, Integer, String, Time, nil] before value from positional args
|
47
59
|
# @param options [Hash] keyword arguments containing after/before values
|
48
60
|
#
|
49
61
|
# @raise [ArgumentError] with appropriate message
|
50
62
|
# @return [void]
|
51
|
-
private def self.raise_being_between_argument_error!: (Array[String] original_caller, (Date | DateTime | String | Time)? after, (Date | DateTime | String | Time)? before, Hash[Symbol, (Date | DateTime | String | Time)?] options) -> void
|
63
|
+
private def self.raise_being_between_argument_error!: (Array[String] original_caller, (Date | DateTime | Integer | String | Time)? after, (Date | DateTime | Integer | String | Time)? before, Hash[Symbol, (Date | DateTime | Integer | String | Time)?] options) -> void
|
52
64
|
|
53
65
|
# Constrain the value to be chronologically after a given date/time
|
54
66
|
#
|
55
|
-
# @param other [Date, DateTime, String, Time] the date/time to compare against
|
67
|
+
# @param other [Date, DateTime, Integer, String, Time] the date/time to compare against
|
56
68
|
# @return [self] self for method chaining
|
57
|
-
def being_after: (Date | DateTime | String | Time other) -> Behavior
|
69
|
+
def being_after: (Date | DateTime | Integer | String | Time other) -> Behavior
|
58
70
|
|
59
71
|
alias after being_after
|
60
72
|
|
61
73
|
# Constrain the value to be chronologically before a given date/time
|
62
74
|
#
|
63
|
-
# @param other [Date, DateTime, String, Time] the date/time to compare against
|
75
|
+
# @param other [Date, DateTime, Integer, String, Time] the date/time to compare against
|
64
76
|
# @return [self] self for method chaining
|
65
|
-
def being_before: (Date | DateTime | String | Time other) -> Behavior
|
77
|
+
def being_before: (Date | DateTime | Integer | String | Time other) -> Behavior
|
66
78
|
|
67
79
|
alias before being_before
|
68
80
|
|
69
81
|
# Constrain the value to be chronologically between two date/times
|
70
82
|
#
|
71
|
-
# @param after [Date, DateTime, String, Time] the earliest allowed date/time
|
72
|
-
# @param before [Date, DateTime, String, Time] the latest allowed date/time
|
83
|
+
# @param after [Date, DateTime, Integer, String, Time] the earliest allowed date/time
|
84
|
+
# @param before [Date, DateTime, Integer, String, Time] the latest allowed date/time
|
73
85
|
# @param options [Hash] alternative way to specify after/before via keywords
|
74
|
-
# @option options [Date, DateTime, String, Time] :after earliest allowed date/time
|
75
|
-
# @option options [Date, DateTime, String, Time] :before latest allowed date/time
|
86
|
+
# @option options [Date, DateTime, Integer, String, Time] :after earliest allowed date/time
|
87
|
+
# @option options [Date, DateTime, Integer, String, Time] :before latest allowed date/time
|
76
88
|
# @return [self] self for method chaining
|
77
|
-
def being_between: (Date | DateTime | String | Time after, Date | DateTime | String | Time before) -> Behavior
|
89
|
+
def being_between: (Date | DateTime | Integer | String | Time after, Date | DateTime | Integer | String | Time before) -> Behavior
|
78
90
|
|
79
91
|
alias between being_between
|
80
92
|
|
81
93
|
# Constrain the value to be exactly equal to a given date/time
|
82
94
|
#
|
83
|
-
# @param other [Date, DateTime, String, Time] the date/time to compare against
|
95
|
+
# @param other [Date, DateTime, Integer, String, Time] the date/time to compare against
|
84
96
|
# @return [self] self for method chaining
|
85
|
-
def being_equal_to: (Date | DateTime | String | Time other) -> Behavior
|
97
|
+
def being_equal_to: (Date | DateTime | Integer | String | Time other) -> Behavior
|
86
98
|
|
87
99
|
alias at being_equal_to
|
88
100
|
|
89
101
|
# Constrain the value to be chronologically on or after a given date/time
|
90
102
|
#
|
91
|
-
# @param other [Date, DateTime, String, Time] the date/time to compare against
|
103
|
+
# @param other [Date, DateTime, Integer, String, Time] the date/time to compare against
|
92
104
|
# @return [self] self for method chaining
|
93
|
-
def being_on_or_after: (Date | DateTime | String | Time other) -> Behavior
|
105
|
+
def being_on_or_after: (Date | DateTime | Integer | String | Time other) -> Behavior
|
94
106
|
|
95
107
|
alias at_or_after being_on_or_after
|
96
108
|
|
@@ -100,9 +112,9 @@ module Domainic
|
|
100
112
|
|
101
113
|
# Constrain the value to be chronologically on or before a given date/time
|
102
114
|
#
|
103
|
-
# @param other [Date, DateTime, String, Time] the date/time to compare against
|
115
|
+
# @param other [Date, DateTime, Integer, String, Time] the date/time to compare against
|
104
116
|
# @return [self] self for method chaining
|
105
|
-
def being_on_or_before: (Date | DateTime | String | Time other) -> Behavior
|
117
|
+
def being_on_or_before: (Date | DateTime | Integer | String | Time other) -> Behavior
|
106
118
|
|
107
119
|
alias at_or_before being_on_or_before
|
108
120
|
|
@@ -125,6 +125,15 @@ module Domainic
|
|
125
125
|
# @return [void]
|
126
126
|
def initialize: (**untyped) -> void
|
127
127
|
|
128
|
+
# Add a custom constraint to this type.
|
129
|
+
#
|
130
|
+
# @param proc [Proc] the constraint to add
|
131
|
+
# @param accessor [Type::Accessor] the accessor to constrain
|
132
|
+
# @param options [Hash{Symbol => Object}] additional constraint options
|
133
|
+
#
|
134
|
+
# @return [self] for chaining constraints
|
135
|
+
def satisfies: (Proc proc, ?accessor: Type::accessor, **untyped options) -> Behavior
|
136
|
+
|
128
137
|
# Convert the type to a String representation.
|
129
138
|
#
|
130
139
|
# @return [String] The type as a String
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Domainic
|
2
|
+
module Type
|
3
|
+
module Constraint
|
4
|
+
# A constraint for validating values using a custom predicate function.
|
5
|
+
#
|
6
|
+
# This constraint allows for custom validation logic through a Proc that returns
|
7
|
+
# a boolean value. It enables users to create arbitrary validation rules when
|
8
|
+
# the built-in constraints don't cover their specific needs.
|
9
|
+
#
|
10
|
+
# @example Basic usage
|
11
|
+
# constraint = PredicateConstraint.new(:self, ->(x) { x > 0 })
|
12
|
+
# constraint.satisfied?(1) # => true
|
13
|
+
# constraint.satisfied?(-1) # => false
|
14
|
+
#
|
15
|
+
# @example With custom violation description
|
16
|
+
# constraint = PredicateConstraint.new(:self, ->(x) { x > 0 }, violation_description: 'not greater than zero')
|
17
|
+
# constraint.satisfied?(-1) # => false
|
18
|
+
# constraint.short_violation_description # => "not greater than zero"
|
19
|
+
#
|
20
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
21
|
+
# @since 0.1.0
|
22
|
+
class PredicateConstraint
|
23
|
+
type expected = ^(untyped value) -> bool
|
24
|
+
|
25
|
+
type options = { ?violation_description: String }
|
26
|
+
|
27
|
+
include Behavior[expected, untyped, options]
|
28
|
+
|
29
|
+
# Get a description of what the constraint expects.
|
30
|
+
#
|
31
|
+
# @note This constraint type does not provide a description as predicates are arbitrary.
|
32
|
+
#
|
33
|
+
# @return [String] an empty string
|
34
|
+
def short_description: ...
|
35
|
+
|
36
|
+
# Get a description of why the predicate validation failed.
|
37
|
+
#
|
38
|
+
# @return [String] the custom violation description if provided
|
39
|
+
def short_violation_description: ...
|
40
|
+
|
41
|
+
# Check if the value satisfies the predicate function.
|
42
|
+
#
|
43
|
+
# @return [Boolean] true if the predicate returns true
|
44
|
+
def satisfies_constraint?: ...
|
45
|
+
|
46
|
+
# Validate that the expectation is a Proc.
|
47
|
+
#
|
48
|
+
# @param expectation [Object] the expectation to validate
|
49
|
+
#
|
50
|
+
# @raise [ArgumentError] if the expectation is not a Proc
|
51
|
+
# @return [void]
|
52
|
+
def validate_expectation!: ...
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -64,6 +64,29 @@ module Domainic
|
|
64
64
|
|
65
65
|
alias _List? _Array?
|
66
66
|
|
67
|
+
# Creates a BigDecimalType instance.
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# type = _BigDecimal
|
71
|
+
# type.validate(BigDecimal('123.45')) # => true
|
72
|
+
#
|
73
|
+
# @param options [Hash] additional configuration options
|
74
|
+
#
|
75
|
+
# @return [Domainic::Type::BigDecimalType] the created type
|
76
|
+
def _BigDecimal: (**__todo__ options) -> BigDecimalType
|
77
|
+
|
78
|
+
# Creates a nilable BigDecimalType instance.
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
# type = _BigDecimal?
|
82
|
+
# type.validate(BigDecimal('123.45')) # => true
|
83
|
+
# type.validate(nil) # => true
|
84
|
+
#
|
85
|
+
# @param options [Hash] additional configuration options
|
86
|
+
#
|
87
|
+
# @return [Domainic::Type::UnionType] the created type (BigDecimal or NilClass)
|
88
|
+
def _BigDecimal?: (**__todo__ options) -> UnionType
|
89
|
+
|
67
90
|
# Creates a Boolean type.
|
68
91
|
#
|
69
92
|
# Represents a union of TrueClass and FalseClass.
|
@@ -111,6 +134,28 @@ module Domainic
|
|
111
134
|
|
112
135
|
alias _Cuid? _CUID?
|
113
136
|
|
137
|
+
# Creates a ComplexType instance.
|
138
|
+
#
|
139
|
+
# @example
|
140
|
+
# type = _Complex
|
141
|
+
# type.validate(Complex(1, 2)) # => true
|
142
|
+
#
|
143
|
+
# @param options [Hash] additional configuration options
|
144
|
+
#
|
145
|
+
# @return [Domainic::Type::ComplexType] the created type
|
146
|
+
def _Complex: (**__todo__ options) -> ComplexType
|
147
|
+
|
148
|
+
# Creates a nilable ComplexType instance.
|
149
|
+
#
|
150
|
+
# @example
|
151
|
+
# type = _Complex?
|
152
|
+
# type.validate(Complex(1, 2)) # => true
|
153
|
+
#
|
154
|
+
# @param options [Hash] additional configuration options
|
155
|
+
#
|
156
|
+
# @return [Domainic::Type::UnionType] the created type (Complex or NilClass)
|
157
|
+
def _Complex?: (**__todo__ options) -> UnionType
|
158
|
+
|
114
159
|
# Creates a DateType instance.
|
115
160
|
#
|
116
161
|
# DateType restricts values to valid `Date` objects.
|
@@ -159,6 +204,34 @@ module Domainic
|
|
159
204
|
# @return [Domainic::Type::UnionType] the created type (DateTimeType or NilClass)
|
160
205
|
def _DateTime?: (**__todo__ options) -> UnionType
|
161
206
|
|
207
|
+
# Creates a DateTimeStringType instance.
|
208
|
+
#
|
209
|
+
# DateTimeStringType restricts values to valid date-time strings.
|
210
|
+
#
|
211
|
+
# @example
|
212
|
+
# type = _DateTimeString
|
213
|
+
# type.validate('2024-01-01T12:00:00Z') # => true
|
214
|
+
#
|
215
|
+
# @param options [Hash] additional configuration options
|
216
|
+
#
|
217
|
+
# @return [Domainic::Type::DateTimeStringType] the created type
|
218
|
+
def _DateTimeString: (**__todo__ options) -> DateTimeStringType
|
219
|
+
|
220
|
+
alias _DateString _DateTimeString
|
221
|
+
|
222
|
+
# Creates a nilable DateTimeStringType instance.
|
223
|
+
#
|
224
|
+
# @example
|
225
|
+
# _DateTimeString? === '2024-01-01T12:00:00Z' # => true
|
226
|
+
# _DateTimeString? === nil # => true
|
227
|
+
#
|
228
|
+
# @param options [Hash] additional configuration options
|
229
|
+
#
|
230
|
+
# @return [Domainic::Type::UnionType] the created type (DateTimeStringType or NilClass)
|
231
|
+
def _DateTimeString?: (**__todo__ options) -> UnionType
|
232
|
+
|
233
|
+
alias _DateString? _DateTimeString?
|
234
|
+
|
162
235
|
# Creates a DuckType instance.
|
163
236
|
#
|
164
237
|
# DuckType allows specifying behavior based on method availability.
|
@@ -395,6 +468,74 @@ module Domainic
|
|
395
468
|
|
396
469
|
alias _Nullable _Nilable
|
397
470
|
|
471
|
+
# Creates a RangeType instance.
|
472
|
+
#
|
473
|
+
# @example
|
474
|
+
# type = _Range
|
475
|
+
# type.validate(1..10) # => true
|
476
|
+
#
|
477
|
+
# @param options [Hash] additional configuration options
|
478
|
+
#
|
479
|
+
# @return [Domainic::Type::RangeType] the created type
|
480
|
+
def _Range: (**__todo__ options) -> RangeType
|
481
|
+
|
482
|
+
# Creates a nilable RangeType instance.
|
483
|
+
#
|
484
|
+
# @example
|
485
|
+
# type = _Range?
|
486
|
+
# type.validate(1..10) # => true
|
487
|
+
#
|
488
|
+
# @param options [Hash] additional configuration options
|
489
|
+
#
|
490
|
+
# @return [Domainic::Type::UnionType] the created type (Range or NilClass)
|
491
|
+
def _Range?: (**__todo__ options) -> UnionType
|
492
|
+
|
493
|
+
# Creates a RationalType instance.
|
494
|
+
#
|
495
|
+
# @example
|
496
|
+
# type = _Rational
|
497
|
+
# type.validate(Rational(1, 2)) # => true
|
498
|
+
#
|
499
|
+
# @param options [Hash] additional configuration options
|
500
|
+
#
|
501
|
+
# @return [Domainic::Type::RationalType] the created type
|
502
|
+
def _Rational: (**__todo__ options) -> RationalType
|
503
|
+
|
504
|
+
# Creates a nilable RationalType instance.
|
505
|
+
#
|
506
|
+
# @example
|
507
|
+
# type = _Rational?
|
508
|
+
# type.validate(Rational(1, 2)) # => true
|
509
|
+
# type.validate(nil) # => true
|
510
|
+
#
|
511
|
+
# @param options [Hash] additional configuration options
|
512
|
+
#
|
513
|
+
# @return [Domainic::Type::UnionType] the created type (Rational or NilClass)
|
514
|
+
def _Rational?: (**__todo__ options) -> UnionType
|
515
|
+
|
516
|
+
# Creates a SetType instance.
|
517
|
+
#
|
518
|
+
# @example
|
519
|
+
# type = _Set
|
520
|
+
# type.validate(Set[1, 2, 3]) # => true
|
521
|
+
#
|
522
|
+
# @param options [Hash] additional configuration options
|
523
|
+
#
|
524
|
+
# @return [Domainic::Type::SetType] the created type
|
525
|
+
def _Set: (**__todo__ options) -> SetType
|
526
|
+
|
527
|
+
# Creates a nilable SetType instance.
|
528
|
+
#
|
529
|
+
# @example
|
530
|
+
# type = _Set?
|
531
|
+
# type.validate(Set[1, 2, 3]) # => true
|
532
|
+
# type.validate(nil) # => true
|
533
|
+
#
|
534
|
+
# @param options [Hash] additional configuration options
|
535
|
+
#
|
536
|
+
# @return [Domainic::Type::UnionType] the created type (Set or NilClass)
|
537
|
+
def _Set?: (**__todo__ options) -> UnionType
|
538
|
+
|
398
539
|
# Creates a StringType instance.
|
399
540
|
#
|
400
541
|
# @example
|
@@ -467,6 +608,30 @@ module Domainic
|
|
467
608
|
# @return [Domainic::Type::UnionType] the created type (TimeType or NilClass)
|
468
609
|
def _Time?: (**__todo__ options) -> UnionType
|
469
610
|
|
611
|
+
# Creates a TimestampType instance.
|
612
|
+
#
|
613
|
+
# TimestampType restricts values to valid timestamps.
|
614
|
+
#
|
615
|
+
# @example
|
616
|
+
# type = _Timestamp
|
617
|
+
# type.validate(1640995200) # => true
|
618
|
+
#
|
619
|
+
# @param options [Hash] additional configuration options
|
620
|
+
#
|
621
|
+
# @return [Domainic::Type::TimestampType] the created type
|
622
|
+
def _Timestamp: (**__todo__ options) -> TimestampType
|
623
|
+
|
624
|
+
# Creates a nilable TimestampType instance.
|
625
|
+
#
|
626
|
+
# @example
|
627
|
+
# _Timestamp? === 1640995200 # => true
|
628
|
+
# _Timestamp? === nil # => true
|
629
|
+
#
|
630
|
+
# @param options [Hash] additional configuration options
|
631
|
+
#
|
632
|
+
# @return [Domainic::Type::UnionType] the created type (TimestampType or NilClass)
|
633
|
+
def _Timestamp?: (**__todo__ options) -> UnionType
|
634
|
+
|
470
635
|
# Creates a URIType instance.
|
471
636
|
#
|
472
637
|
# URIType restricts values to valid URIs.
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Domainic
|
2
|
+
module Type
|
3
|
+
# A type for validating and constraining `Complex` numbers.
|
4
|
+
#
|
5
|
+
# This type extends `NumericBehavior` to provide a fluent interface for numeric-specific validations such as
|
6
|
+
# polarity and divisibility checks.
|
7
|
+
#
|
8
|
+
# @example Validating a `Complex` value
|
9
|
+
# type = Domainic::Type::ComplexType.new
|
10
|
+
# type.validate!(Complex(3, 4)) # => true
|
11
|
+
#
|
12
|
+
# @example Enforcing constraints
|
13
|
+
# type = Domainic::Type::ComplexType.new
|
14
|
+
# type.being_positive.validate!(Complex(42, 0)) # => raises TypeError
|
15
|
+
#
|
16
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
17
|
+
# @since 0.1.0
|
18
|
+
class ComplexType
|
19
|
+
extend Behavior::ClassMethods
|
20
|
+
|
21
|
+
include Behavior
|
22
|
+
|
23
|
+
include Behavior::NumericBehavior
|
24
|
+
|
25
|
+
# Constrain the Complex real to be divisible by a given divisor.
|
26
|
+
#
|
27
|
+
# @param arguments [Array<Numeric>] a list of arguments, typically one divisor
|
28
|
+
# @param options [Hash] additional options such as tolerance for floating-point checks
|
29
|
+
# @option options [Numeric] :divisor the divisor to check for divisibility
|
30
|
+
# @option options [Numeric] :tolerance the tolerance for floating-point checks
|
31
|
+
#
|
32
|
+
# @return [self] the current instance for chaining
|
33
|
+
def being_divisible_by: (*Numeric arguments, ?divisor: Numeric, ?tolerance: Numeric) -> Behavior
|
34
|
+
|
35
|
+
alias being_multiple_of being_divisible_by
|
36
|
+
|
37
|
+
alias divisible_by being_divisible_by
|
38
|
+
|
39
|
+
alias multiple_of being_divisible_by
|
40
|
+
|
41
|
+
# Constrain the Complex real to be even.
|
42
|
+
#
|
43
|
+
# @return [self] the current instance for chaining
|
44
|
+
def being_even: () -> Behavior
|
45
|
+
|
46
|
+
alias even being_even
|
47
|
+
|
48
|
+
alias not_being_odd being_even
|
49
|
+
|
50
|
+
# Constrain the Complex real to be negative.
|
51
|
+
#
|
52
|
+
# @return [self] the current instance for chaining
|
53
|
+
def being_negative: () -> Behavior
|
54
|
+
|
55
|
+
alias negative being_negative
|
56
|
+
|
57
|
+
alias not_being_positive being_negative
|
58
|
+
|
59
|
+
# Constrain the Complex real value to be odd.
|
60
|
+
#
|
61
|
+
# @return [self] the current instance for chaining
|
62
|
+
def being_odd: () -> Behavior
|
63
|
+
|
64
|
+
alias odd being_odd
|
65
|
+
|
66
|
+
alias not_being_even being_odd
|
67
|
+
|
68
|
+
# Constrain the Complex real to be positive.
|
69
|
+
#
|
70
|
+
# @return [self] the current instance for chaining
|
71
|
+
def being_positive: () -> Behavior
|
72
|
+
|
73
|
+
alias positive being_positive
|
74
|
+
|
75
|
+
alias not_being_negative being_positive
|
76
|
+
|
77
|
+
# Constrain the Complex real to not be divisible by a specific divisor.
|
78
|
+
#
|
79
|
+
# @note the divisor MUST be provided as an argument or in the options Hash.
|
80
|
+
#
|
81
|
+
# @param arguments [Array<Numeric>] a list of arguments, typically one divisor
|
82
|
+
# @param options [Hash] additional options such as tolerance for floating-point checks
|
83
|
+
# @option options [Numeric] :divisor the divisor to check for divisibility
|
84
|
+
# @option options [Numeric] :tolerance the tolerance for floating-point checks
|
85
|
+
#
|
86
|
+
# @return [self] the current instance for chaining
|
87
|
+
def not_being_divisible_by: (*Numeric arguments, ?divisor: Numeric, ?tolerance: Numeric) -> Behavior
|
88
|
+
|
89
|
+
alias not_being_multiple_of not_being_divisible_by
|
90
|
+
|
91
|
+
alias not_divisible_by not_being_divisible_by
|
92
|
+
|
93
|
+
alias not_multiple_of not_being_divisible_by
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Domainic
|
2
|
+
module Type
|
3
|
+
# A type for validating `Range` objects with comprehensive constraints.
|
4
|
+
#
|
5
|
+
# This class allows flexible validation of ranges, supporting type checks,
|
6
|
+
# inclusion/exclusion of values, and range-specific behaviors such as bounds validation.
|
7
|
+
# It integrates with `EnumerableBehavior` for enumerable-style validations
|
8
|
+
# (e.g., size constraints, element presence).
|
9
|
+
#
|
10
|
+
# Key features:
|
11
|
+
# - Ensures the value is a `Range`.
|
12
|
+
# - Supports constraints for range boundaries (`begin` and `end`).
|
13
|
+
# - Provides validations for inclusion and exclusion of values.
|
14
|
+
# - Leverages `EnumerableBehavior` for size and collection-style constraints.
|
15
|
+
#
|
16
|
+
# @example Basic usage
|
17
|
+
# type = RangeType.new
|
18
|
+
# type.having_bounds(1, 10) # Validates range bounds (inclusive or exclusive).
|
19
|
+
# type.containing(5) # Ensures value is within the range.
|
20
|
+
# type.not_containing(15) # Ensures value is not within the range.
|
21
|
+
#
|
22
|
+
# @example Integration with EnumerableBehavior
|
23
|
+
# type = RangeType.new
|
24
|
+
# type.having_size(10) # Validates size (total elements in the range).
|
25
|
+
# type.containing_exactly(3, 7) # Validates specific values within the range.
|
26
|
+
#
|
27
|
+
# @example Flexible boundaries
|
28
|
+
# type = RangeType.new
|
29
|
+
# type.having_bounds(1, 10, exclusive: true) # Upper and lower bounds are exclusive.
|
30
|
+
#
|
31
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
32
|
+
# @since 0.1.0
|
33
|
+
class RangeType
|
34
|
+
extend Behavior::ClassMethods
|
35
|
+
|
36
|
+
include Behavior
|
37
|
+
|
38
|
+
include Behavior::EnumerableBehavior
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Domainic
|
2
|
+
module Type
|
3
|
+
# A type for validating Rational numbers.
|
4
|
+
#
|
5
|
+
# This type ensures values are of type `Rational` and supports a range of
|
6
|
+
# constraints for numerical validation, such as positivity, negativity,
|
7
|
+
# and divisibility. It integrates with `NumericBehavior` to provide a
|
8
|
+
# consistent and fluent interface for numeric constraints.
|
9
|
+
#
|
10
|
+
# @example Validating a positive Rational number
|
11
|
+
# type = Domainic::Type::RationalType.new
|
12
|
+
# type.being_positive.validate!(Rational(3, 4)) # => true
|
13
|
+
#
|
14
|
+
# @example Validating divisibility
|
15
|
+
# type = Domainic::Type::RationalType.new
|
16
|
+
# type.being_divisible_by(1).validate!(Rational(3, 1)) # => true
|
17
|
+
#
|
18
|
+
# @example Using constraints with chaining
|
19
|
+
# type = Domainic::Type::RationalType.new
|
20
|
+
# type.being_greater_than(0).being_less_than(1).validate!(Rational(1, 2)) # => true
|
21
|
+
#
|
22
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
23
|
+
# @since 0.1.0
|
24
|
+
class RationalType
|
25
|
+
extend Behavior::ClassMethods
|
26
|
+
|
27
|
+
include Behavior
|
28
|
+
|
29
|
+
include Behavior::NumericBehavior
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Domainic
|
2
|
+
module Type
|
3
|
+
# A type for validating and constraining `BigDecimal` objects.
|
4
|
+
#
|
5
|
+
# This type extends `NumericBehavior` to provide a fluent interface for numeric-specific validations such as being
|
6
|
+
# positive, being within a range, or satisfying divisibility rules.
|
7
|
+
#
|
8
|
+
# @example Validating a `BigDecimal` value
|
9
|
+
# type = Domainic::Type::BigDecimalType.new
|
10
|
+
# type.validate!(BigDecimal('3.14')) # => true
|
11
|
+
#
|
12
|
+
# @example Enforcing constraints
|
13
|
+
# type = Domainic::Type::BigDecimalType.new
|
14
|
+
# type.being_positive.validate!(BigDecimal('42')) # => true
|
15
|
+
# type.being_positive.validate!(BigDecimal('-42')) # raises TypeError
|
16
|
+
#
|
17
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
18
|
+
# @since 0.1.0
|
19
|
+
class BigDecimalType
|
20
|
+
extend Behavior::ClassMethods
|
21
|
+
|
22
|
+
include Behavior
|
23
|
+
|
24
|
+
include Behavior::NumericBehavior
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|