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/hashes.rb
CHANGED
@@ -1,208 +1,256 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# ========================================================================
|
6
|
+
|
7
|
+
# Project / Package
|
8
|
+
# ------------------------------------------------------------------------
|
9
|
+
|
1
10
|
require_relative './type'
|
11
|
+
|
12
|
+
|
13
|
+
# Namespace
|
14
|
+
# ========================================================================
|
15
|
+
|
16
|
+
module NRSER
|
17
|
+
module Types
|
18
|
+
|
19
|
+
|
20
|
+
# Definitions
|
21
|
+
# ========================================================================
|
22
|
+
|
23
|
+
# A type who's members simply are {Hash} instances.
|
24
|
+
#
|
25
|
+
# Implements {#from_s} to provide JSON/YAML detection, as well as "simple"
|
26
|
+
# loading aimed at CLI option values.
|
27
|
+
#
|
28
|
+
# @note
|
29
|
+
# Construct {HashType} types using the {.Hash} factory.
|
30
|
+
#
|
31
|
+
class HashType < IsA
|
32
|
+
|
33
|
+
# Constructor
|
34
|
+
# ========================================================================
|
35
|
+
|
36
|
+
# Instantiate a new `HashType`.
|
37
|
+
def initialize **options
|
38
|
+
super ::Hash, **options
|
39
|
+
end # #initialize
|
2
40
|
|
3
|
-
module NRSER::Types
|
4
41
|
|
5
|
-
#
|
42
|
+
# Instance Methods
|
43
|
+
# ========================================================================
|
44
|
+
|
45
|
+
# In order to provide the same interface as {HashOfType}, this method
|
46
|
+
# always returns {NRSER::Types.any}.
|
6
47
|
#
|
7
|
-
#
|
8
|
-
# loading aimed at CLI option values.
|
48
|
+
# @return [NRSER::Types::Type]
|
9
49
|
#
|
10
|
-
|
50
|
+
def keys; NRSER::Types.Top; end
|
11
51
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# In order to provide the same interface as {HashOfType}, this method
|
33
|
-
# always returns {NRSER::Types.any}.
|
34
|
-
#
|
35
|
-
# @return [NRSER::Types::Type]
|
52
|
+
|
53
|
+
# In order to provide the same interface as {HashOfType}, this method
|
54
|
+
# always returns {NRSER::Types.any}.
|
55
|
+
#
|
56
|
+
# @return [NRSER::Types::Type]
|
57
|
+
#
|
58
|
+
def values; NRSER::Types.Top; end
|
59
|
+
|
60
|
+
|
61
|
+
def default_symbolic
|
62
|
+
"{#{ keys.symbolic }#{ ASSOC }#{ values.symbolic }}"
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
protected
|
67
|
+
# ========================================================================
|
68
|
+
|
69
|
+
# Hook to provide custom loading from strings, which will be called by
|
70
|
+
# {NRSER::Types::Type#from_s}, unless a `@from_s`
|
36
71
|
#
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
def custom_from_s string
|
47
|
-
# Does it looks like a JSON / inline-YAML object?
|
48
|
-
if NRSER.looks_like_json_object? string
|
49
|
-
# It does! Load it
|
50
|
-
begin
|
51
|
-
return YAML.load string
|
52
|
-
rescue
|
53
|
-
# pass - if we failed to load as JSON, it may just not be JSON, and
|
54
|
-
# we can try the split approach below.
|
55
|
-
end
|
72
|
+
def custom_from_s string
|
73
|
+
# Does it looks like a JSON / inline-YAML object?
|
74
|
+
if NRSER.looks_like_json_object? string
|
75
|
+
# It does! Load it
|
76
|
+
begin
|
77
|
+
return YAML.load string
|
78
|
+
rescue
|
79
|
+
# pass - if we failed to load as JSON, it may just not be JSON, and
|
80
|
+
# we can try the split approach below.
|
56
81
|
end
|
57
|
-
|
58
|
-
# Try parsing as a "simple string", aimed at CLI option values.
|
59
|
-
from_simple_s string
|
60
82
|
end
|
61
83
|
|
84
|
+
# Try parsing as a "simple string", aimed at CLI option values.
|
85
|
+
from_simple_s string
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
def from_simple_s string
|
90
|
+
hash = {}
|
62
91
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
92
|
+
pair_strs = string.split NRSER::Types::ArrayType::DEFAULT_SPLIT_WITH
|
93
|
+
|
94
|
+
pair_strs.each do |pair_str|
|
95
|
+
key_str, match, value_str = pair_str.rpartition /\:\s*/m
|
67
96
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
2. Then by the last `:` in each of those splits (also followed)
|
84
|
-
by any amount of whitespace)
|
85
|
-
END
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
key = if keys == NRSER::Types.any
|
90
|
-
key_str
|
91
|
-
else
|
92
|
-
keys.from_s key_str
|
97
|
+
if match.empty?
|
98
|
+
raise NRSER::Types::FromStringError.new(
|
99
|
+
"Could not split pair string", pair_str,
|
100
|
+
type: self,
|
101
|
+
string: string,
|
102
|
+
pair_str: pair_str,
|
103
|
+
) do
|
104
|
+
<<~END
|
105
|
+
Trying to parse a {Hash} out of a string using the "simple"
|
106
|
+
approach, which splits
|
107
|
+
|
108
|
+
1. First by `,` (followed by any amount of whitespace)
|
109
|
+
2. Then by the last `:` in each of those splits (also followed)
|
110
|
+
by any amount of whitespace)
|
111
|
+
END
|
93
112
|
end
|
94
|
-
|
95
|
-
value = if values == NRSER::Types.any
|
96
|
-
value_str
|
97
|
-
else
|
98
|
-
values.from_s value_str
|
99
|
-
end
|
100
|
-
|
101
|
-
hash[key] = value
|
102
113
|
end
|
103
114
|
|
104
|
-
|
105
|
-
|
115
|
+
key = if keys == NRSER::Types.any
|
116
|
+
key_str
|
117
|
+
else
|
118
|
+
keys.from_s key_str
|
119
|
+
end
|
120
|
+
|
121
|
+
value = if values == NRSER::Types.any
|
122
|
+
value_str
|
123
|
+
else
|
124
|
+
values.from_s value_str
|
125
|
+
end
|
126
|
+
|
127
|
+
hash[key] = value
|
128
|
+
end
|
106
129
|
|
107
|
-
|
130
|
+
hash
|
131
|
+
end # #from_simple_s
|
108
132
|
|
109
|
-
|
133
|
+
public # end protected *****************************************************
|
134
|
+
|
135
|
+
end # class HashType
|
136
|
+
|
137
|
+
|
138
|
+
# A {Hash} type with typed keys and/or values.
|
139
|
+
#
|
140
|
+
# @note
|
141
|
+
# Construct {HashOfType} types using the {.Hash} factory.
|
142
|
+
#
|
143
|
+
|
144
|
+
class HashOfType < HashType
|
110
145
|
|
146
|
+
# Attributes
|
147
|
+
# ========================================================================
|
111
148
|
|
112
|
-
#
|
149
|
+
# The type of the hash keys.
|
113
150
|
#
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
# Constructor
|
134
|
-
# ========================================================================
|
135
|
-
|
136
|
-
def initialize keys: NRSER::Types.any,
|
137
|
-
values: NRSER::Types.any,
|
138
|
-
**options
|
139
|
-
super **options
|
140
|
-
|
141
|
-
@keys = NRSER::Types.make keys
|
142
|
-
@values = NRSER::Types.make values
|
143
|
-
end
|
144
|
-
|
145
|
-
|
146
|
-
# Instance Methods
|
147
|
-
# ========================================================================
|
148
|
-
|
149
|
-
# Overridden to check that both the {#keys} and {#values} types can
|
150
|
-
# load from a string.
|
151
|
-
#
|
152
|
-
# @see NRSER::Types::Type#has_from_s?
|
153
|
-
#
|
154
|
-
def has_from_s?
|
155
|
-
!@from_s.nil? || [keys, values].all?( &:has_from_s )
|
156
|
-
end
|
157
|
-
|
158
|
-
|
159
|
-
# @see NRSER::Types::Type#test
|
160
|
-
#
|
161
|
-
# @return [Boolean]
|
162
|
-
#
|
163
|
-
def test? value
|
164
|
-
return false unless super( value )
|
165
|
-
|
166
|
-
value.all? { |k, v|
|
167
|
-
keys.test( k ) && values.test( v )
|
168
|
-
}
|
169
|
-
end
|
170
|
-
|
171
|
-
|
172
|
-
# @see NRSER::Types::Type#explain
|
173
|
-
#
|
174
|
-
# @return [String]
|
175
|
-
#
|
176
|
-
def explain
|
177
|
-
"Hash<#{ keys.explain }, #{ values.explain }>"
|
178
|
-
end
|
179
|
-
|
180
|
-
end # HashType
|
151
|
+
# @return [NRSER::Types::Type]
|
152
|
+
#
|
153
|
+
attr_reader :keys
|
154
|
+
|
155
|
+
|
156
|
+
# The type of the hash values.
|
157
|
+
#
|
158
|
+
# @return [NRSER::Types::Type]
|
159
|
+
#
|
160
|
+
attr_reader :values
|
161
|
+
|
162
|
+
|
163
|
+
# Constructor
|
164
|
+
# ========================================================================
|
165
|
+
|
166
|
+
def initialize keys: NRSER::Types.any,
|
167
|
+
values: NRSER::Types.any,
|
168
|
+
**options
|
169
|
+
super **options
|
181
170
|
|
171
|
+
@keys = NRSER::Types.make keys
|
172
|
+
@values = NRSER::Types.make values
|
173
|
+
end
|
174
|
+
|
182
175
|
|
183
|
-
#
|
176
|
+
# Instance Methods
|
177
|
+
# ========================================================================
|
178
|
+
|
179
|
+
# Overridden to check that both the {#keys} and {#values} types can
|
180
|
+
# load from a string.
|
184
181
|
#
|
185
|
-
# @
|
186
|
-
# Passed to {NRSER::Types::HashType#initialize} unless empty.
|
182
|
+
# @see NRSER::Types::Type#has_from_s?
|
187
183
|
#
|
188
|
-
|
189
|
-
|
184
|
+
def has_from_s?
|
185
|
+
!@from_s.nil? || [keys, values].all?( &:has_from_s )
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
# @see NRSER::Types::Type#test
|
190
190
|
#
|
191
|
-
# @return [
|
192
|
-
# Newly constructed hash type from `args`.
|
191
|
+
# @return [Boolean]
|
193
192
|
#
|
194
|
-
|
195
|
-
|
193
|
+
def test? value
|
194
|
+
return false unless super( value )
|
195
|
+
|
196
|
+
value.all? { |k, v|
|
197
|
+
keys.test( k ) && values.test( v )
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
# @see NRSER::Types::Type#explain
|
196
203
|
#
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
if kwds.key?( :keys ) || kwds.key?( :values )
|
202
|
-
HashOfType.new **kwds
|
203
|
-
else
|
204
|
-
HashType.new **kwds
|
205
|
-
end
|
204
|
+
# @return [String]
|
205
|
+
#
|
206
|
+
def explain
|
207
|
+
"Hash<#{ keys.explain }, #{ values.explain }>"
|
206
208
|
end
|
207
209
|
|
208
|
-
end
|
210
|
+
end # HashType
|
211
|
+
|
212
|
+
|
213
|
+
# @!group Hash Type Factories
|
214
|
+
# ----------------------------------------------------------------------------
|
215
|
+
|
216
|
+
# @!method self.Hash keys: self.Top, values: self.Top, **options
|
217
|
+
# Type satisfied by {Hash} instances with optional key and value types.
|
218
|
+
#
|
219
|
+
# @param [TYPE] keys
|
220
|
+
# Type for the hash keys. Will be made into a type by {.make} if it's not
|
221
|
+
# one already.
|
222
|
+
#
|
223
|
+
# **WARNING** Don't pass `nil` unless you mean that all the keys must be
|
224
|
+
# `nil`! Omit the keyword or pass {.Top}.
|
225
|
+
#
|
226
|
+
# @param [TYPE] values
|
227
|
+
# Type for the hash values. Will be made into a type by {.make} if it's not
|
228
|
+
# one already.
|
229
|
+
#
|
230
|
+
# **WARNING** Don't pass `nil` unless you mean that all the values must be
|
231
|
+
# `nil`! Omit the keyword or pass {.Top}.
|
232
|
+
#
|
233
|
+
# @param [Hash] options
|
234
|
+
# Passed to {Type#initialize}.
|
235
|
+
#
|
236
|
+
# @return [HashType]
|
237
|
+
#
|
238
|
+
def_type :Hash,
|
239
|
+
aliases: [ :dict, :hash_type ],
|
240
|
+
parameterize: [ :keys, :values ],
|
241
|
+
&->( keys: self.Top, values: self.Top, **options ) do
|
242
|
+
if keys != self.Top || values != self.Top
|
243
|
+
HashOfType.new keys: keys, values: values, **options
|
244
|
+
else
|
245
|
+
HashType.new **options
|
246
|
+
end
|
247
|
+
end # .Hash
|
248
|
+
|
249
|
+
# @!endgroup Hash Type Factories # *******************************************
|
250
|
+
|
251
|
+
|
252
|
+
# /Namespace
|
253
|
+
# ========================================================================
|
254
|
+
|
255
|
+
end # module Types
|
256
|
+
end # module NRSER
|
data/lib/nrser/types/in.rb
CHANGED
@@ -1,39 +1,76 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Project / Package
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
require 'nrser/errors/type_error'
|
11
|
+
|
12
|
+
# Namespace
|
13
|
+
# ========================================================================
|
14
|
+
|
15
|
+
module NRSER
|
16
|
+
module Types
|
17
|
+
|
18
|
+
|
19
|
+
# Definitions
|
20
|
+
# ========================================================================
|
21
|
+
|
22
|
+
# @!group In Type Factories
|
23
|
+
# ----------------------------------------------------------------------------
|
24
|
+
|
25
|
+
#@!method self.In group, **options
|
26
|
+
# Type that tests value for membership in a group object via that object's
|
27
|
+
# `#include?` method.
|
28
|
+
#
|
29
|
+
# @todo
|
30
|
+
# I think I want to get rid of {.where}... which would elevate this to
|
31
|
+
# it's own class as a "fundamental" concept (I guess)... not so sure,
|
32
|
+
# really. The idea of membership is pretty wide-spread and important,
|
33
|
+
# but it's a bit a vague and inconsistently implemented things.
|
34
|
+
#
|
35
|
+
# @param [#include?] group
|
36
|
+
# `#include?` will be called on this value to determine type membership.
|
37
|
+
#
|
38
|
+
# @param [Hash] options
|
39
|
+
# Passed to {Type#initialize}.
|
40
|
+
#
|
41
|
+
# @return [Type]
|
42
|
+
#
|
43
|
+
# @raise [NRSER::TypeError]
|
44
|
+
# If `group` doesn't respond to `#include?`.
|
45
|
+
#
|
46
|
+
def_type :In,
|
47
|
+
aliases: [ :member_of ],
|
48
|
+
from_s: ->( s ) { s },
|
49
|
+
default_name: ->( group, **options ) {
|
50
|
+
"In<#{ NRSER.smart_ellipsis group.inspect, 64 }>"
|
51
|
+
},
|
52
|
+
parameterize: :group,
|
53
|
+
&->( group, **options ) do
|
54
|
+
unless group.respond_to? :include?
|
55
|
+
raise NRSER::TypeError,
|
56
|
+
"In `group` must respond to `:include?`",
|
57
|
+
group: group
|
58
|
+
end
|
59
|
+
|
60
|
+
# TODO This is a step in the right direction (from anon {Proc}) but I
|
61
|
+
# now think what we really want is
|
62
|
+
#
|
63
|
+
# where group, :include?
|
64
|
+
#
|
65
|
+
self.Where group.method( :include? ), **options
|
66
|
+
end # .In
|
67
|
+
|
68
|
+
# @!endgroup In Type Factories # *********************************************
|
69
|
+
|
70
|
+
|
71
|
+
# /Namespace
|
72
|
+
# ========================================================================
|
73
|
+
|
74
|
+
end # module Types
|
75
|
+
end # module NRSER
|
76
|
+
|