domainic-type 0.1.0.alpha.2.1.0 → 0.1.0.alpha.3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- 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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f21061b605848ed1ca2638a2819c3ad56949df1690a09d7f703d52c62c8d8720
|
|
4
|
+
data.tar.gz: 35b51a1be388dd8a0ef55f58b0bb8e7190d0c1666984bfe340dfef597fe80519
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30d67d75036848bae0ad52b09c276af2e560f2227f1bee01499893b4dd43fcdd6deefd444e4839bd92cde586674671634912cc203e4ce7eb2bc3d71ee77e5cc3
|
|
7
|
+
data.tar.gz: 61e0e722906fe09d3df96e63412523b51c62dc4df9a7190f7127e18fa26c68215f44e6626d9368e140d103f6284866b7ded63b94faceafc66feaa4096b2f6624
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog], and this project adheres to [Break Versioning].
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
[Keep a Changelog]: https://keepachangelog.com/en/1.0.0/
|
|
10
|
+
[Break Versioning]: https://www.taoensso.com/break-versioning
|
|
11
|
+
|
|
12
|
+
<!-- versions -->
|
|
13
|
+
|
|
14
|
+
[Unreleased]: https://github.com/domainic/domainic/tree/main/domainic-type
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,7 +1,31 @@
|
|
|
1
|
-
# Domainic
|
|
1
|
+
# Domainic::Type
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://rubygems.org/gems/domainic-type)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
[](https://github.com/domainic/domainic/issues?q=state%3Aopen%20label%3Adomainic-type%20)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
> [!IMPORTANT]
|
|
8
|
+
> We're running an experiment with Domainic::Type! Help us explore flexible type validation in Ruby by trying our
|
|
9
|
+
> [alpha release](../docs/experiments/domainic-type-alpha-3/README.md). Your feedback is invaluable for shaping
|
|
10
|
+
> the future of domain-driven design in Ruby.
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
A flexible type validation system for Ruby, offering composable, readable type constraints with elegant error messages.
|
|
13
|
+
|
|
14
|
+
Stop wrestling with complex type validations and unclear error messages. Domainic::Type brings type validation to Ruby
|
|
15
|
+
that is both powerful and delightful to use. Build composable type constraints with crystal-clear error messages that
|
|
16
|
+
actually tell you what went wrong. From simple type checks to complex collection validations, make your types work for
|
|
17
|
+
you, not against you!
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
Add this line to your application's Gemfile:
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
gem 'domainic-type', '~> 0.1.0.alpha.3'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or install it yourself as:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
gem install domainic-type --pre
|
|
31
|
+
```
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Domainic
|
|
4
|
+
module Type
|
|
5
|
+
# @rbs!
|
|
6
|
+
# type accessor = :abs | :begin | :chars | :class | :count | :end | :entries | :first | :keys | :last | :length |
|
|
7
|
+
# :self | :size | :values
|
|
8
|
+
|
|
9
|
+
# A list of valid access methods that can be used to retrieve values for constraint validation.
|
|
10
|
+
# These methods represent common Ruby interfaces for accessing collection sizes, ranges, and values.
|
|
11
|
+
#
|
|
12
|
+
# - :abs - For absolute values
|
|
13
|
+
# - :begin, :end - For Range-like objects
|
|
14
|
+
# - :class - For type checking
|
|
15
|
+
# - :count, :length, :size - For measuring collections
|
|
16
|
+
# - :entries, :chars - For accessing sequence elements
|
|
17
|
+
# - :first, :last - For accessing sequence endpoints
|
|
18
|
+
# - :keys, :values - For Hash-like objects
|
|
19
|
+
# - :self - For operating directly on the value
|
|
20
|
+
#
|
|
21
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
|
22
|
+
# @since 0.1.0
|
|
23
|
+
# @return [Array<Symbol>]
|
|
24
|
+
ACCESSORS = %i[
|
|
25
|
+
class
|
|
26
|
+
self
|
|
27
|
+
entries
|
|
28
|
+
chars
|
|
29
|
+
abs
|
|
30
|
+
count
|
|
31
|
+
size
|
|
32
|
+
length
|
|
33
|
+
first
|
|
34
|
+
last
|
|
35
|
+
begin
|
|
36
|
+
end
|
|
37
|
+
keys
|
|
38
|
+
values
|
|
39
|
+
].freeze #: Array[accessor]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'domainic/type/behavior'
|
|
4
|
+
require 'domainic/type/behavior/sizable_behavior'
|
|
5
|
+
|
|
6
|
+
module Domainic
|
|
7
|
+
module Type
|
|
8
|
+
module Behavior
|
|
9
|
+
# A module providing enumerable-specific validation behaviors for types.
|
|
10
|
+
#
|
|
11
|
+
# This module extends the base Type::Behavior with methods specifically designed for validating enumerable
|
|
12
|
+
# collections. It provides a fluent interface for common enumerable validations such as uniqueness, emptiness,
|
|
13
|
+
# ordering, and size constraints.
|
|
14
|
+
#
|
|
15
|
+
# @example Basic usage
|
|
16
|
+
# class ArrayType
|
|
17
|
+
# include Domainic::Type::Behavior::EnumerableBehavior
|
|
18
|
+
#
|
|
19
|
+
# def initialize
|
|
20
|
+
# super
|
|
21
|
+
# being_empty # validates array is empty
|
|
22
|
+
# having_minimum_count(5) # validates at least 5 elements
|
|
23
|
+
# containing(1, 2, 3) # validates specific elements
|
|
24
|
+
# end
|
|
25
|
+
# end
|
|
26
|
+
#
|
|
27
|
+
# @example Combining constraints
|
|
28
|
+
# class OrderedArrayType
|
|
29
|
+
# include Domainic::Type::Behavior::EnumerableBehavior
|
|
30
|
+
#
|
|
31
|
+
# def initialize
|
|
32
|
+
# super
|
|
33
|
+
# being_ordered
|
|
34
|
+
# being_populated
|
|
35
|
+
# having_maximum_count(10)
|
|
36
|
+
# end
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# @author {https://aaronmallen.me Aaron Allen}
|
|
40
|
+
# @since 0.1.0
|
|
41
|
+
module EnumerableBehavior
|
|
42
|
+
include SizableBehavior
|
|
43
|
+
|
|
44
|
+
def being_distinct
|
|
45
|
+
# @type self: Object & Behavior
|
|
46
|
+
constrain :entries, :uniqueness, description: 'being'
|
|
47
|
+
end
|
|
48
|
+
alias being_unique being_distinct
|
|
49
|
+
alias distinct being_distinct
|
|
50
|
+
alias unique being_distinct
|
|
51
|
+
|
|
52
|
+
# Validate that the enumerable contains duplicate elements.
|
|
53
|
+
#
|
|
54
|
+
# Creates an inverse uniqueness constraint that ensures the collection has at least one duplicate element.
|
|
55
|
+
#
|
|
56
|
+
# @example
|
|
57
|
+
# type.being_duplicative
|
|
58
|
+
# type.validate([1, 1, 2]) # => true
|
|
59
|
+
# type.validate([1, 2, 3]) # => false
|
|
60
|
+
#
|
|
61
|
+
# @return [self] self for method chaining
|
|
62
|
+
# @rbs ()-> Behavior
|
|
63
|
+
def being_duplicative
|
|
64
|
+
# @type self: Object & Behavior
|
|
65
|
+
unique = @constraints.prepare :self, :uniqueness
|
|
66
|
+
constrain :entries, :not, unique, concerning: :uniqueness, description: 'being'
|
|
67
|
+
end
|
|
68
|
+
alias being_redundant being_duplicative
|
|
69
|
+
alias being_repetitive being_duplicative
|
|
70
|
+
alias duplicative being_duplicative
|
|
71
|
+
alias redundant being_duplicative
|
|
72
|
+
alias repetitive being_duplicative
|
|
73
|
+
|
|
74
|
+
# Validate that the enumerable is empty.
|
|
75
|
+
#
|
|
76
|
+
# Creates a constraint that ensures the collection has no elements.
|
|
77
|
+
#
|
|
78
|
+
# @example
|
|
79
|
+
# type.being_empty
|
|
80
|
+
# type.validate([]) # => true
|
|
81
|
+
# type.validate([1]) # => false
|
|
82
|
+
#
|
|
83
|
+
# @return [self] self for method chaining
|
|
84
|
+
# @rbs ()-> Behavior
|
|
85
|
+
def being_empty
|
|
86
|
+
# @type self: Object & Behavior
|
|
87
|
+
constrain :entries, :emptiness, description: 'being'
|
|
88
|
+
end
|
|
89
|
+
alias being_vacant being_empty
|
|
90
|
+
alias empty being_empty
|
|
91
|
+
alias vacant being_empty
|
|
92
|
+
|
|
93
|
+
# Validate that the enumerable contains elements.
|
|
94
|
+
#
|
|
95
|
+
# Creates an inverse emptiness constraint that ensures the collection has at least one element.
|
|
96
|
+
#
|
|
97
|
+
# @example
|
|
98
|
+
# type.being_populated
|
|
99
|
+
# type.validate([1]) # => true
|
|
100
|
+
# type.validate([]) # => false
|
|
101
|
+
#
|
|
102
|
+
# @return [self] self for method chaining
|
|
103
|
+
# @rbs ()-> Behavior
|
|
104
|
+
def being_populated
|
|
105
|
+
# @type self: Object & Behavior
|
|
106
|
+
empty = @constraints.prepare :self, :emptiness
|
|
107
|
+
constrain :entries, :not, empty, concerning: :emptiness, description: 'being'
|
|
108
|
+
end
|
|
109
|
+
alias being_inhabited being_populated
|
|
110
|
+
alias being_occupied being_populated
|
|
111
|
+
alias populated being_populated
|
|
112
|
+
alias inhabited being_populated
|
|
113
|
+
alias occupied being_populated
|
|
114
|
+
|
|
115
|
+
# Validate that the enumerable elements are in sorted order.
|
|
116
|
+
#
|
|
117
|
+
# Creates a constraint that ensures the collection's elements are in ascending order based on their natural
|
|
118
|
+
# comparison methods.
|
|
119
|
+
#
|
|
120
|
+
# @example
|
|
121
|
+
# type.being_ordered
|
|
122
|
+
# type.validate([1, 2, 3]) # => true
|
|
123
|
+
# type.validate([3, 1, 2]) # => false
|
|
124
|
+
#
|
|
125
|
+
# @return [self] self for method chaining
|
|
126
|
+
# @rbs ()-> Behavior
|
|
127
|
+
def being_sorted
|
|
128
|
+
# @type self: Object & Behavior
|
|
129
|
+
constrain :entries, :ordering, description: 'being'
|
|
130
|
+
end
|
|
131
|
+
alias being_aranged being_sorted
|
|
132
|
+
alias being_ordered being_sorted
|
|
133
|
+
alias being_sequential being_sorted
|
|
134
|
+
alias aranged being_sorted
|
|
135
|
+
alias ordered being_sorted
|
|
136
|
+
alias sorted being_sorted
|
|
137
|
+
alias sequential being_sorted
|
|
138
|
+
|
|
139
|
+
# Validate that the enumerable elements are not in sorted order.
|
|
140
|
+
#
|
|
141
|
+
# Creates an inverse ordering constraint that ensures the collection's elements are not in ascending order.
|
|
142
|
+
#
|
|
143
|
+
# @example
|
|
144
|
+
# type.being_unordered
|
|
145
|
+
# type.validate([3, 1, 2]) # => true
|
|
146
|
+
# type.validate([1, 2, 3]) # => false
|
|
147
|
+
#
|
|
148
|
+
# @return [self] self for method chaining
|
|
149
|
+
# @rbs ()-> Behavior
|
|
150
|
+
def being_unsorted
|
|
151
|
+
# @type self: Object & Behavior
|
|
152
|
+
ordered = @constraints.prepare :self, :ordering
|
|
153
|
+
constrain :entries, :not, ordered, concerning: :ordering, description: 'being'
|
|
154
|
+
end
|
|
155
|
+
alias being_disordered being_unsorted
|
|
156
|
+
alias being_unordered being_unsorted
|
|
157
|
+
alias disordered being_unsorted
|
|
158
|
+
alias unsorted being_unsorted
|
|
159
|
+
alias unordered being_unsorted
|
|
160
|
+
|
|
161
|
+
# Validate that the enumerable contains specific entries.
|
|
162
|
+
#
|
|
163
|
+
# Creates a series of inclusion constraints ensuring the collection contains all specified elements.
|
|
164
|
+
#
|
|
165
|
+
# @example
|
|
166
|
+
# type.containing(1, 2)
|
|
167
|
+
# type.validate([1, 2, 3]) # => true
|
|
168
|
+
# type.validate([1, 3]) # => false
|
|
169
|
+
#
|
|
170
|
+
# @param entries [Array<Object>] the elements that must be present
|
|
171
|
+
# @return [self] self for method chaining
|
|
172
|
+
# @rbs (*untyped entries)-> Behavior
|
|
173
|
+
def containing(*entries)
|
|
174
|
+
# @type self: Object & Behavior
|
|
175
|
+
including = entries.map do |entry|
|
|
176
|
+
@constraints.prepare :entries, :inclusion, entry
|
|
177
|
+
end
|
|
178
|
+
constrain :entries, :and, including, concerning: :entry_inclusion
|
|
179
|
+
end
|
|
180
|
+
alias including containing
|
|
181
|
+
|
|
182
|
+
# Validate that the enumerable contains a specific last entry.
|
|
183
|
+
#
|
|
184
|
+
# Creates an equality constraint on the collection's last entry ensuring it is equal to the specified value.
|
|
185
|
+
#
|
|
186
|
+
# @example
|
|
187
|
+
# type.having_last_entry(3)
|
|
188
|
+
# type.validate([1, 2, 3]) # => true
|
|
189
|
+
# type.validate([1, 3, 2]) # => false
|
|
190
|
+
#
|
|
191
|
+
# @param literal [Object] the value that must be the last entry
|
|
192
|
+
# @return [self] self for method chaining
|
|
193
|
+
# @rbs (untyped literal)-> Behavior
|
|
194
|
+
def ending_with(literal)
|
|
195
|
+
# @type self: Object & Behavior
|
|
196
|
+
constrain :last, :equality, literal, concerning: :last_entry_value, description: 'with last entry'
|
|
197
|
+
end
|
|
198
|
+
alias closing_with ending_with
|
|
199
|
+
alias finishing_with ending_with
|
|
200
|
+
|
|
201
|
+
# Validate that the enumerable does not contain specific entries.
|
|
202
|
+
#
|
|
203
|
+
# Creates a series of exclusion constraints ensuring the collection does not contain any of the specified
|
|
204
|
+
# elements.
|
|
205
|
+
#
|
|
206
|
+
# @example
|
|
207
|
+
# type.excluding(1, 2)
|
|
208
|
+
# type.validate([3, 4, 5]) # => true
|
|
209
|
+
# type.validate([1, 2, 3]) # => false
|
|
210
|
+
#
|
|
211
|
+
# @param entries [Array<Object>] the elements that must not be present
|
|
212
|
+
# @return [self] self for method chaining
|
|
213
|
+
# @rbs (*untyped entries)-> Behavior
|
|
214
|
+
def excluding(*entries)
|
|
215
|
+
# @type self: Object & Behavior
|
|
216
|
+
including = entries.map do |entry|
|
|
217
|
+
@constraints.prepare :entries, :inclusion, entry
|
|
218
|
+
end
|
|
219
|
+
constrain :entries, :nor, including, concerning: :entry_exclusion
|
|
220
|
+
end
|
|
221
|
+
alias omitting excluding
|
|
222
|
+
|
|
223
|
+
# Validate that the enumerable contains elements of a specific type.
|
|
224
|
+
#
|
|
225
|
+
# Creates a type constraint on the collection's elements ensuring they are all of the specified type.
|
|
226
|
+
#
|
|
227
|
+
# @example
|
|
228
|
+
# type.of(String)
|
|
229
|
+
# type.validate(['a', 'b', 'c']) # => true
|
|
230
|
+
# type.validate(['a', 1, 'c']) # => false
|
|
231
|
+
#
|
|
232
|
+
# @param type [Class, Module, Behavior] the type that all elements must be
|
|
233
|
+
# @return [self] self for method chaining
|
|
234
|
+
# @rbs (Class | Module | Behavior type)-> Behavior
|
|
235
|
+
def of(type)
|
|
236
|
+
# @type self: Object & Behavior
|
|
237
|
+
type = @constraints.prepare :self, :type, type
|
|
238
|
+
constrain :entries, :all, type, concerning: :entry_type
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Validate that the enumerable contains a specific first entry.
|
|
242
|
+
#
|
|
243
|
+
# Creates an equality constraint on the collection's first entry ensuring it is equal to the specified value.
|
|
244
|
+
#
|
|
245
|
+
# @example
|
|
246
|
+
# type.having_first_entry(1)
|
|
247
|
+
# type.validate([1, 2, 3]) # => true
|
|
248
|
+
# type.validate([2, 3, 1]) # => false
|
|
249
|
+
#
|
|
250
|
+
# @param literal [Object] the value that must be the first entry
|
|
251
|
+
# @return [self] self for method chaining
|
|
252
|
+
# @rbs (untyped literal)-> Behavior
|
|
253
|
+
def starting_with(literal)
|
|
254
|
+
# @type self: Object & Behavior
|
|
255
|
+
constrain :first, :equality, literal, concerning: :first_entry_value, description: 'with first entry'
|
|
256
|
+
end
|
|
257
|
+
alias begining_with starting_with
|
|
258
|
+
alias leading_with starting_with
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|