nrser 0.3.9 → 0.3.10
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/lib/nrser/char/alpha_numeric_sub.rb +9 -19
- data/lib/nrser/char/special.rb +5 -5
- data/lib/nrser/core_ext/array.rb +36 -13
- data/lib/nrser/core_ext/enumerable.rb +1 -0
- data/lib/nrser/core_ext/enumerable/find_map.rb +1 -1
- data/lib/nrser/core_ext/hash/bury.rb +3 -0
- data/lib/nrser/core_ext/hash/extract_values_at.rb +2 -2
- data/lib/nrser/core_ext/method/full_name.rb +1 -1
- data/lib/nrser/core_ext/module/method_objects.rb +1 -1
- data/lib/nrser/core_ext/module/source_locations.rb +27 -15
- data/lib/nrser/core_ext/object/lazy_var.rb +1 -1
- data/lib/nrser/core_ext/pathname.rb +67 -12
- data/lib/nrser/core_ext/pathname/subpath.rb +86 -0
- data/lib/nrser/core_ext/string.rb +28 -1
- data/lib/nrser/core_ext/symbol.rb +11 -12
- data/lib/nrser/errors/README.md +154 -0
- data/lib/nrser/errors/attr_error.rb +146 -53
- data/lib/nrser/errors/count_error.rb +61 -12
- data/lib/nrser/errors/nicer_error.rb +42 -71
- data/lib/nrser/errors/value_error.rb +53 -58
- data/lib/nrser/functions.rb +0 -2
- data/lib/nrser/functions/enumerable.rb +5 -17
- data/lib/nrser/functions/enumerable/associate.rb +14 -5
- data/lib/nrser/functions/enumerable/find_all_map.rb +1 -1
- data/lib/nrser/functions/enumerable/include_slice/array_include_slice.rb +1 -1
- data/lib/nrser/functions/hash/bury.rb +2 -12
- data/lib/nrser/functions/merge_by.rb +2 -2
- data/lib/nrser/functions/module/method_objects.rb +2 -2
- data/lib/nrser/functions/path.rb +185 -165
- data/lib/nrser/functions/path/normalized.rb +84 -0
- data/lib/nrser/functions/string.rb +4 -4
- data/lib/nrser/functions/text/README.md +4 -0
- data/lib/nrser/functions/text/format.rb +53 -0
- data/lib/nrser/functions/text/indentation.rb +6 -6
- data/lib/nrser/functions/text/word_wrap.rb +2 -2
- data/lib/nrser/functions/tree/map_leaves.rb +3 -3
- data/lib/nrser/functions/tree/map_tree.rb +2 -2
- data/lib/nrser/functions/tree/transform.rb +1 -18
- data/lib/nrser/gem_ext/README.md +4 -0
- data/lib/nrser/labs/README.md +8 -0
- data/lib/nrser/labs/config.rb +163 -0
- data/lib/nrser/labs/i8.rb +49 -159
- data/lib/nrser/labs/i8/struct.rb +167 -0
- data/lib/nrser/labs/i8/struct/hash.rb +140 -0
- data/lib/nrser/labs/i8/struct/vector.rb +149 -0
- data/lib/nrser/labs/i8/surjection.rb +211 -0
- data/lib/nrser/labs/lots/consumer.rb +19 -0
- data/lib/nrser/labs/lots/parser.rb +21 -1
- data/lib/nrser/labs/stash.rb +4 -4
- data/lib/nrser/log.rb +25 -21
- data/lib/nrser/log/appender/sync.rb +15 -11
- data/lib/nrser/log/formatters/color.rb +0 -3
- data/lib/nrser/log/formatters/mixin.rb +4 -4
- data/lib/nrser/log/logger.rb +54 -6
- data/lib/nrser/log/mixin.rb +2 -1
- data/lib/nrser/log/plugin.rb +6 -6
- data/lib/nrser/log/types.rb +46 -29
- data/lib/nrser/mean_streak.rb +0 -8
- data/lib/nrser/mean_streak/document.rb +1 -4
- data/lib/nrser/message.rb +3 -3
- data/lib/nrser/meta/README.md +4 -0
- data/lib/nrser/meta/lazy_attr.rb +2 -2
- data/lib/nrser/meta/source/location.rb +1 -1
- data/lib/nrser/props.rb +34 -3
- data/lib/nrser/props/class_methods.rb +2 -1
- data/lib/nrser/props/instance_methods.rb +9 -9
- data/lib/nrser/props/metadata.rb +4 -12
- data/lib/nrser/props/mutable/stash.rb +5 -2
- data/lib/nrser/props/prop.rb +10 -19
- data/lib/nrser/rspex.rb +1 -20
- data/lib/nrser/rspex/example_group/describe_attribute.rb +3 -0
- data/lib/nrser/rspex/example_group/describe_called_with.rb +9 -4
- data/lib/nrser/rspex/example_group/describe_case.rb +1 -0
- data/lib/nrser/rspex/example_group/describe_class.rb +2 -0
- data/lib/nrser/rspex/example_group/describe_group.rb +1 -1
- data/lib/nrser/rspex/example_group/describe_instance.rb +3 -1
- data/lib/nrser/rspex/example_group/describe_message.rb +1 -1
- data/lib/nrser/rspex/example_group/describe_method.rb +64 -30
- data/lib/nrser/rspex/example_group/describe_response_to.rb +1 -1
- data/lib/nrser/rspex/example_group/describe_section.rb +4 -1
- data/lib/nrser/rspex/example_group/describe_sent_to.rb +1 -1
- data/lib/nrser/rspex/example_group/describe_setup.rb +1 -0
- data/lib/nrser/rspex/example_group/describe_source_file.rb +1 -1
- data/lib/nrser/rspex/example_group/describe_spec_file.rb +4 -2
- data/lib/nrser/rspex/example_group/describe_when.rb +2 -1
- data/lib/nrser/rspex/example_group/describe_x.rb +5 -5
- data/lib/nrser/rspex/format.rb +0 -15
- data/lib/nrser/sugar/method_missing_forwarder.rb +3 -3
- data/lib/nrser/sys/env/path.rb +2 -28
- data/lib/nrser/types.rb +63 -12
- data/lib/nrser/types/README.md +76 -0
- data/lib/nrser/types/arrays.rb +192 -137
- data/lib/nrser/types/attributes.rb +269 -0
- data/lib/nrser/types/booleans.rb +134 -83
- data/lib/nrser/types/bounded.rb +110 -47
- data/lib/nrser/types/collections.rb +119 -0
- data/lib/nrser/types/combinators.rb +283 -196
- data/lib/nrser/types/doc/display_table.md +66 -0
- data/lib/nrser/types/eqiuvalent.rb +91 -0
- data/lib/nrser/types/errors/check_error.rb +5 -11
- data/lib/nrser/types/errors/from_string_error.rb +3 -3
- data/lib/nrser/types/factory.rb +287 -20
- data/lib/nrser/types/hashes.rb +227 -179
- data/lib/nrser/types/in.rb +73 -36
- data/lib/nrser/types/is.rb +67 -60
- data/lib/nrser/types/is_a.rb +141 -84
- data/lib/nrser/types/labels.rb +45 -16
- data/lib/nrser/types/maybe.rb +6 -3
- data/lib/nrser/types/nil.rb +64 -27
- data/lib/nrser/types/not.rb +92 -34
- data/lib/nrser/types/numbers.rb +224 -169
- data/lib/nrser/types/pairs.rb +113 -89
- data/lib/nrser/types/paths.rb +250 -137
- data/lib/nrser/types/responds.rb +167 -89
- data/lib/nrser/types/selector.rb +234 -0
- data/lib/nrser/types/shape.rb +136 -65
- data/lib/nrser/types/strings.rb +189 -63
- data/lib/nrser/types/symbols.rb +83 -33
- data/lib/nrser/types/top.rb +89 -0
- data/lib/nrser/types/tuples.rb +134 -98
- data/lib/nrser/types/type.rb +617 -505
- data/lib/nrser/types/when.rb +123 -98
- data/lib/nrser/types/where.rb +182 -91
- data/lib/nrser/version.rb +1 -1
- data/spec/lib/nrser/core_ext/pathname/subpath_spec.rb +22 -0
- data/spec/lib/nrser/errors/attr_error_spec.rb +68 -0
- data/spec/lib/nrser/errors/count_error_spec.rb +69 -0
- data/spec/lib/nrser/functions/path/normalize_path_spec.rb +35 -0
- data/spec/lib/nrser/functions/tree/map_tree_spec.rb +74 -96
- data/spec/lib/nrser/functions/tree/transform_spec.rb +11 -11
- data/spec/lib/nrser/labs/config_spec.rb +22 -0
- data/spec/lib/nrser/labs/i8/struct_spec.rb +39 -0
- data/spec/lib/nrser/types/display_spec.rb +50 -0
- data/spec/lib/nrser/types/paths_spec.rb +16 -10
- data/spec/lib/nrser/types/selector_spec.rb +125 -0
- data/spec/spec_helper.rb +4 -5
- metadata +105 -22
- data/lib/nrser/types/any.rb +0 -41
- data/lib/nrser/types/attrs.rb +0 -213
- data/lib/nrser/types/trees.rb +0 -42
data/lib/nrser/types/responds.rb
CHANGED
@@ -1,100 +1,178 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
1
4
|
require 'nrser/message'
|
2
5
|
require_relative './booleans'
|
3
6
|
|
4
|
-
|
7
|
+
|
8
|
+
# Namespace
|
9
|
+
# ========================================================================
|
10
|
+
|
11
|
+
module NRSER
|
12
|
+
module Types
|
13
|
+
|
14
|
+
|
15
|
+
# Definitions
|
16
|
+
# ========================================================================
|
17
|
+
|
18
|
+
# This {Type} is used to test how the values in question respond to specific
|
19
|
+
# messages (method calls).
|
20
|
+
#
|
21
|
+
# {Respond} instances hold a {#message} and {#response} type. Instances
|
22
|
+
# that respond when sent the message with a value that satisfies the
|
23
|
+
# response type are members.
|
24
|
+
#
|
25
|
+
# @example Type whose members have non-empty string names.
|
26
|
+
# type = Types:Respond.new \
|
27
|
+
# to: :name,
|
28
|
+
# with: Types.non_empty_str
|
29
|
+
#
|
30
|
+
class Respond < Type
|
31
|
+
|
32
|
+
# Attributes
|
33
|
+
# ======================================================================
|
5
34
|
|
6
|
-
#
|
7
|
-
# that respond with a value that satisfies the respond type when sent the
|
8
|
-
# message.
|
35
|
+
# Message that will be sent to tested values.
|
9
36
|
#
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
37
|
+
# @return [NRSER::Message]
|
38
|
+
#
|
39
|
+
attr_reader :message
|
40
|
+
|
41
|
+
|
42
|
+
# Type tested values must respond with when sent the message.
|
43
|
+
#
|
44
|
+
# @return [Type]
|
45
|
+
#
|
46
|
+
attr_reader :response
|
47
|
+
|
48
|
+
|
49
|
+
# Controls whether the {#message} will be sent using `#public_send` (the
|
50
|
+
# default) or `#send` - which has access to private and protected
|
51
|
+
# methods.
|
52
|
+
#
|
53
|
+
# @return [Boolean]
|
54
|
+
#
|
55
|
+
attr_reader :publicly
|
56
|
+
|
57
|
+
|
58
|
+
# Constructor
|
59
|
+
# ======================================================================
|
60
|
+
|
61
|
+
# Instantiate a new instance.
|
62
|
+
#
|
63
|
+
# See construction example in the class header: {Respond}.
|
64
|
+
#
|
65
|
+
# @param [String | Symbol | Array] to
|
66
|
+
# Fed in to {NRSER::Message.from} to create the {#message}.
|
67
|
+
#
|
68
|
+
# Must be a lone string or symbol representing the method name to call,
|
69
|
+
# or an Array with the string or symbol methods name in the first entry
|
70
|
+
# (and whatever other parameters can follow it).
|
71
|
+
#
|
72
|
+
# @param [Type | Object] with
|
73
|
+
# The type members must respond with. If `with:` is not a {Type} it will
|
74
|
+
# be made into on via {Types.make}.
|
75
|
+
#
|
76
|
+
# @param [Boolean] publicly
|
77
|
+
# Chooses between using `#public_send` and `#send` to send the {#message}.
|
78
|
+
#
|
79
|
+
# @param [Hash] options
|
80
|
+
# Additional options that will be passed up to {Type#initialize}.
|
81
|
+
#
|
82
|
+
def initialize to:,
|
83
|
+
with:,
|
84
|
+
publicly: true,
|
85
|
+
**options
|
86
|
+
@message = NRSER::Message.from *to
|
87
|
+
@publicly = publicly
|
88
|
+
@response = NRSER::Types.make with
|
89
|
+
|
90
|
+
super **options
|
91
|
+
end # #initialize
|
92
|
+
|
93
|
+
|
94
|
+
# Instance Methods
|
95
|
+
# ======================================================================
|
96
|
+
|
97
|
+
# See {Type#explain}.
|
98
|
+
#
|
99
|
+
# @param (see Type#explain)
|
100
|
+
# @return (see Type#explain)
|
101
|
+
# @raise (see Type#explain)
|
102
|
+
#
|
103
|
+
def explain
|
104
|
+
args_str = message.args.map( &:inspect ).join ', '
|
56
105
|
|
57
|
-
|
58
|
-
|
59
|
-
# @param (see NRSER::Types::Type#explain)
|
60
|
-
# @return (see NRSER::Types::Type#explain)
|
61
|
-
# @raise (see NRSER::Types::Type#explain)
|
62
|
-
#
|
63
|
-
def explain
|
64
|
-
args_str = message.args.map( &:inspect ).join ', '
|
65
|
-
|
66
|
-
if message.block
|
67
|
-
args_str += ', ' + message.block.to_s
|
68
|
-
end
|
69
|
-
|
70
|
-
"##{ message.symbol }(#{ args_str })#{ RESPONDS_WITH }#{ response.explain }"
|
106
|
+
if message.block
|
107
|
+
args_str += ', ' + message.block.to_s
|
71
108
|
end
|
72
109
|
|
73
|
-
|
74
|
-
|
75
|
-
#
|
76
|
-
# @param (see NRSER::Types::Type#test?)
|
77
|
-
# @return (see NRSER::Types::Type#test?)
|
78
|
-
# @raise (see NRSER::Types::Type#test?)
|
79
|
-
#
|
80
|
-
def test? value
|
81
|
-
response.test message.send_to( value, publicly: publicly )
|
82
|
-
end # #test
|
83
|
-
|
84
|
-
end # class Responds
|
110
|
+
"##{ message.symbol }(#{ args_str })#{ RESPONDS_WITH }#{ response.explain }"
|
111
|
+
end
|
85
112
|
|
86
|
-
|
87
|
-
def_factory(
|
88
|
-
:respond,
|
89
|
-
) do |*args|
|
90
|
-
Respond.new *args
|
91
|
-
end # #responds
|
92
113
|
|
114
|
+
# Test value for membership.
|
115
|
+
#
|
116
|
+
# @param (see Type#test?)
|
117
|
+
# @return (see Type#test?)
|
118
|
+
# @raise (see Type#test?)
|
119
|
+
#
|
120
|
+
def test? value
|
121
|
+
response.test message.send_to( value, publicly: publicly )
|
122
|
+
end # #test
|
93
123
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
124
|
+
end # class Responds
|
125
|
+
|
126
|
+
|
127
|
+
# Factories
|
128
|
+
# ----------------------------------------------------------------------------
|
129
|
+
|
130
|
+
# @!group Method Response Type Factories
|
131
|
+
# ----------------------------------------------------------------------------
|
132
|
+
|
133
|
+
#@!method self.Respond to:, with:, publicly: true, **options
|
134
|
+
# Create a {Respond} type.
|
135
|
+
#
|
136
|
+
# @param (see Respond#initialize)
|
137
|
+
#
|
138
|
+
# @return [Respond]
|
139
|
+
#
|
140
|
+
def_type :Respond,
|
141
|
+
default_name: false,
|
142
|
+
parameterize: [ :to, :with, :publicly ],
|
143
|
+
&->( to:, with:, publicly: true, **options ) do
|
144
|
+
Respond.new to: to, with: with, publicly: publicly, **options
|
145
|
+
end # .Respond
|
146
|
+
|
147
|
+
|
148
|
+
#@!method self.RespondTo method_name, **options
|
149
|
+
# Gets a {Respond} that admits values that `#respond_to?` a `method_name`.
|
150
|
+
#
|
151
|
+
# @param [Symbol | String] method_name
|
152
|
+
# The name of the method that type members must `#respond_to?`.
|
153
|
+
#
|
154
|
+
# @param [Hash] options
|
155
|
+
# Passed to {Type#initialize}.
|
156
|
+
#
|
157
|
+
# @return [Respond]
|
158
|
+
#
|
159
|
+
def_type :RespondTo,
|
160
|
+
default_name: ->( method_name, **options ) {
|
161
|
+
"RespondTo<#{ method_name }>"
|
162
|
+
},
|
163
|
+
parameterize: :method_name,
|
164
|
+
# TODO I'm not sure how this worked before, but defining `.respond_to?`
|
165
|
+
# def fucks things up...
|
166
|
+
# maybe: false,
|
167
|
+
&->( method_name, **options ) do
|
168
|
+
respond to: [:respond_to?, method_name], with: self.True
|
169
|
+
end # .RespondTo
|
170
|
+
|
171
|
+
# @!endgroup Method Response Type Factories # ********************************
|
172
|
+
|
173
|
+
|
174
|
+
# /Namespace
|
175
|
+
# ========================================================================
|
176
|
+
|
177
|
+
end # module Types
|
178
|
+
end # module NRSER
|
@@ -0,0 +1,234 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Project / Package
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
require_relative './combinators'
|
11
|
+
require_relative './when'
|
12
|
+
require_relative './shape'
|
13
|
+
require_relative './collections'
|
14
|
+
|
15
|
+
|
16
|
+
# Namespace
|
17
|
+
# =======================================================================
|
18
|
+
|
19
|
+
module NRSER
|
20
|
+
module Types
|
21
|
+
|
22
|
+
|
23
|
+
# Definitions
|
24
|
+
# =======================================================================
|
25
|
+
|
26
|
+
# @!group Selector Type Factories
|
27
|
+
# ----------------------------------------------------------------------------
|
28
|
+
|
29
|
+
#@!method self.Selector pairs, **options
|
30
|
+
# Factory to create {Shape} type instances that function as MongoDB-esque
|
31
|
+
# document query against lists of Ruby objects using the standard
|
32
|
+
# {Enumerable#select} and related methods.
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# # Some sample data
|
36
|
+
#
|
37
|
+
# people = [
|
38
|
+
# {name: "Neil", fav_color: "blue", likes: ["cat", "scotch", "computer"]},
|
39
|
+
# {name: "Mica", fav_color: "red", like: ["cat", "beer", "dance"]},
|
40
|
+
# ]
|
41
|
+
#
|
42
|
+
# # Simple value matching
|
43
|
+
#
|
44
|
+
# people.select( &t[ name: "Neil" ] ).map &[:name]
|
45
|
+
# # => [ "Neil" ]
|
46
|
+
#
|
47
|
+
# # NOTE 1. We're using the `t -> NRSER::Types` short-hand alias, as
|
48
|
+
# # provided by `using NRSER::Types` refinement.
|
49
|
+
# #
|
50
|
+
# # 2. {NRSER::Types.[]} is a short-hand alias for
|
51
|
+
# # {NRSER::Types.Selector}.
|
52
|
+
# #
|
53
|
+
# # 3. The `&[:name]` uses NRSER's {Array#to_proc} core extension.
|
54
|
+
# # It's equivalent to `{ |h| h[:name] }`.
|
55
|
+
# #
|
56
|
+
#
|
57
|
+
# people.select( &t[ fav_color: "red" ] ).map &[:name]
|
58
|
+
# # => [ "Mica" ]
|
59
|
+
#
|
60
|
+
# # Fields that are {NRSER::Types.Bag} (think Array and Set but not Hash)
|
61
|
+
# # match against *any* of the values
|
62
|
+
#
|
63
|
+
# people.select( &t[ likes: "cat" ] ).map &[:name]
|
64
|
+
# # => [ "Neil", "Mica" ]
|
65
|
+
#
|
66
|
+
# # Literal arrays are treated like literals, however, and must match
|
67
|
+
# # *exactly*
|
68
|
+
#
|
69
|
+
# people.select( &t[ likes: [ "cat", "computer" ] ] ).map &[:name]
|
70
|
+
# # => []
|
71
|
+
#
|
72
|
+
# people.select( &t[ likes: [ "cat", "computer", "scotch" ] ] ).map &[:name]
|
73
|
+
# # => []
|
74
|
+
#
|
75
|
+
# people.select( &t[ likes: [ "cat", "scotch", "computer" ] ] ).map &[:name]
|
76
|
+
# # => ["Neil"]
|
77
|
+
#
|
78
|
+
# # To match against *any* of a list of terms you can construct a
|
79
|
+
# # {NRSER::Types.HasAny}
|
80
|
+
#
|
81
|
+
# people.select( &t[ likes: t.HasAny( "computer", "dance" ) ]).map &[:name]
|
82
|
+
# # => ["Neil", "Mica"]
|
83
|
+
#
|
84
|
+
# # The {NRSER::Types.Has} and {.HasAny} do create types for the terms and
|
85
|
+
# # do a `#find` against them, so you can use any of the {NRSER::Types}
|
86
|
+
# # system in there.
|
87
|
+
# #
|
88
|
+
# # Here is using a {RegExp} (which {NRSER::Types.make} wraps in a
|
89
|
+
# # {NRSER::Types::When}):
|
90
|
+
#
|
91
|
+
# people.select( &t[ fav_color: /\A[bg]/ ] ).map &[:name]
|
92
|
+
#
|
93
|
+
# Selectors are in the very early and experimental stage, but it's something
|
94
|
+
# I've been thinking about for a while now that suddenly just sort-of fell
|
95
|
+
# into place.
|
96
|
+
#
|
97
|
+
# Eventually I want to be able to use these same selectors on SQL, MongoDB,
|
98
|
+
# ActiveRecord, etc.
|
99
|
+
#
|
100
|
+
# @see https://docs.mongodb.com/manual/tutorial/query-documents/
|
101
|
+
# MongoDB Query Tutorial
|
102
|
+
# @see https://docs.mongodb.com/manual/reference/operator/query/
|
103
|
+
# MongoDB Query and Projection Operators
|
104
|
+
#
|
105
|
+
# @status
|
106
|
+
# Experimental
|
107
|
+
#
|
108
|
+
# @param [Hash<Object, TYPE>] pairs
|
109
|
+
# Keys will be the keys in the resulting {.Shape} type.
|
110
|
+
#
|
111
|
+
# Values that are {Type} instances are used as is for the {Shape} value
|
112
|
+
# type. Everything else gets run through
|
113
|
+
#
|
114
|
+
# @param [Hash] options
|
115
|
+
# Passed to {Type#initialize}.
|
116
|
+
#
|
117
|
+
# @return [Shape]
|
118
|
+
#
|
119
|
+
def_type :Selector,
|
120
|
+
aliases: [ :query, :[] ],
|
121
|
+
# I don't think we need the `?` methods for Selector?
|
122
|
+
maybe: false,
|
123
|
+
parameterize: :pairs,
|
124
|
+
&->( pairs, **options ) do
|
125
|
+
shape \
|
126
|
+
pairs.transform_values { |value|
|
127
|
+
if value.is_a?( Type )
|
128
|
+
value
|
129
|
+
else
|
130
|
+
value_type = self.When value
|
131
|
+
self.or(
|
132
|
+
value_type,
|
133
|
+
(bag & has( value_type )),
|
134
|
+
name: "{#{ value.inspect }}"
|
135
|
+
)
|
136
|
+
end
|
137
|
+
},
|
138
|
+
**options
|
139
|
+
end # .Selector
|
140
|
+
|
141
|
+
# @!endgroup Selector Type Factories # ***************************************
|
142
|
+
|
143
|
+
|
144
|
+
# @!group Find Type Factories
|
145
|
+
# ----------------------------------------------------------------------------
|
146
|
+
#
|
147
|
+
|
148
|
+
# @method self.Has member, **options
|
149
|
+
#
|
150
|
+
# Type that tests value for membership in a group object via that object's
|
151
|
+
# `#include?` method.
|
152
|
+
#
|
153
|
+
# @todo
|
154
|
+
# The "find" factories got introduced to support {.Selector}, and need
|
155
|
+
# improvement. They're really just stop gaps at the moment, and have
|
156
|
+
# already been considerably changed a few times.
|
157
|
+
#
|
158
|
+
# I want to eventually make selectors able to output SQL, MongoDB, etc.
|
159
|
+
# queries, which will require we get rid of the {.Where} usage...
|
160
|
+
#
|
161
|
+
# @status
|
162
|
+
# Experimental
|
163
|
+
#
|
164
|
+
# @param [Object] member
|
165
|
+
# The object that needs to be included for type satisfaction.
|
166
|
+
#
|
167
|
+
# @param [Hash] options
|
168
|
+
# Passed to {Type#initialize}.
|
169
|
+
#
|
170
|
+
# @return [Type]
|
171
|
+
#
|
172
|
+
def_type :Has,
|
173
|
+
parameterize: :member,
|
174
|
+
aliases: [ :has, :includes ],
|
175
|
+
&->( member, **options ) do
|
176
|
+
# Provide a some-what useful default name
|
177
|
+
options[:name] ||= "Has<#{ NRSER.smart_ellipsis member.inspect, 64 }>"
|
178
|
+
|
179
|
+
member_type = make member
|
180
|
+
|
181
|
+
where( **options ) { |value|
|
182
|
+
value.respond_to?( :find ) &&
|
183
|
+
# value.find { |entry| member_type === entry }
|
184
|
+
value.find( &member_type )
|
185
|
+
}
|
186
|
+
end # .Has
|
187
|
+
|
188
|
+
|
189
|
+
#@!method self.HasAny *members, **options
|
190
|
+
# Match values that have *any* of `members`.
|
191
|
+
#
|
192
|
+
# @todo
|
193
|
+
# The "find" factories got introduced to support {.Selector}, and need
|
194
|
+
# improvement. They're really just stop gaps at the moment, and have
|
195
|
+
# already been considerably changed a few times.
|
196
|
+
#
|
197
|
+
# I want to eventually make selectors able to output SQL, MongoDB, etc.
|
198
|
+
# queries, which will require we get rid of the {.Where} usage...
|
199
|
+
#
|
200
|
+
# @status
|
201
|
+
# Experimental
|
202
|
+
#
|
203
|
+
# @param [Array<TYPE>] members
|
204
|
+
# Resulting type will be satisfied by values in which it can `#find` any
|
205
|
+
# entry that any of `members` is satisfied by. `members` entries that are
|
206
|
+
# not {Type} instances will be made into them via {.make}.
|
207
|
+
#
|
208
|
+
# @param [Hash] options
|
209
|
+
# Passed to {Type#initialize}.
|
210
|
+
#
|
211
|
+
# @return [Type]
|
212
|
+
#
|
213
|
+
def_type :HasAny,
|
214
|
+
parameterize: :members,
|
215
|
+
aliases: [ :intersects ],
|
216
|
+
&->( *members, **options ) do
|
217
|
+
options[:name] ||= \
|
218
|
+
"HasAny<#{ NRSER.smart_ellipsis members.inspect, 64 }>"
|
219
|
+
|
220
|
+
member_types = members.map { |m| make m }
|
221
|
+
|
222
|
+
where( **options ) {
|
223
|
+
|group| member_types.any? { |member_type| group.find &member_type }
|
224
|
+
}
|
225
|
+
end # .HasAny
|
226
|
+
|
227
|
+
# @!endgroup Find Type Factories # *******************************************
|
228
|
+
|
229
|
+
# /Namespace
|
230
|
+
# =======================================================================
|
231
|
+
|
232
|
+
end # module Types
|
233
|
+
end # module NRSER
|
234
|
+
|