domainic-type 0.1.0.alpha.2.1.0 → 0.1.0.alpha.3.0.1
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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e4f8e0bb4883a197a5ed2f87b53a6dbc60ae70a41f48f6369881e8a5a5249b0
|
4
|
+
data.tar.gz: b512246f56da3aa04d9b068c080324a7ab507f96b6749a6ed8701a8bc8615901
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d807fab460c97af3e8fc50acb0f834ae8bc881d56507c668908d1baaa3b983516280a79c361fe30da893e38aeffa04561f265605c9c33633c64578a4461550f
|
7
|
+
data.tar.gz: c243d9fc6559e8d3be625c7db153d9964d2e36bcda90a33ba2e75f0cb8e69269cfa53542dddabf8fa7a4671da676bde29db7ae4893c5659d1702f38ff5a8f50f
|
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
|
+
[![Domainic::Type Version](https://img.shields.io/gem/v/domainic-type?style=for-the-badge&logo=rubygems&logoColor=white&logoSize=auto&label=Gem%20Version)](https://rubygems.org/gems/domainic-type)
|
4
|
+
[![Domainic::Type License](https://img.shields.io/github/license/domainic/domainic?logo=opensourceinitiative&logoColor=white&logoSize=auto&style=for-the-badge)](./LICENSE)
|
5
|
+
[![Domainic::Type Open Issues](https://img.shields.io/github/issues-search/domainic/domainic?label=open%20issues&logo=github&logoSize=auto&query=is%3Aopen%20label%3Adomainic-type&color=red&style=for-the-badge)](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
|