nrser 0.2.2 → 0.3.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/lib/nrser/char/alpha_numeric_sub.rb +1 -2
- data/lib/nrser/char.rb +0 -6
- data/lib/nrser/core_ext/array.rb +120 -0
- data/lib/nrser/core_ext/binding.rb +44 -0
- data/lib/nrser/{functions → core_ext}/enumerable/find_map.rb +18 -15
- data/lib/nrser/{ext → core_ext}/enumerable.rb +10 -24
- data/lib/nrser/core_ext/exception.rb +30 -0
- data/lib/nrser/core_ext/hash/extract_values_at.rb +49 -0
- data/lib/nrser/core_ext/hash/transform_values_with_keys.rb +24 -0
- data/lib/nrser/core_ext/hash.rb +50 -0
- data/lib/nrser/core_ext/module/method_objects.rb +96 -0
- data/lib/nrser/core_ext/module/names.rb +69 -0
- data/lib/nrser/core_ext/module/source_locations.rb +214 -0
- data/lib/nrser/core_ext/module.rb +2 -0
- data/lib/nrser/core_ext/object/lazy_var.rb +31 -0
- data/lib/nrser/core_ext/object.rb +46 -0
- data/lib/nrser/core_ext/open_struct.rb +6 -0
- data/lib/nrser/{ext → core_ext}/pathname.rb +8 -5
- data/lib/nrser/{ext → core_ext}/string.rb +6 -12
- data/lib/nrser/core_ext/symbol.rb +13 -0
- data/lib/nrser/core_ext/time.rb +46 -0
- data/lib/nrser/core_ext.rb +13 -0
- data/lib/nrser/errors/abstract_method_error.rb +150 -0
- data/lib/nrser/errors/argument_error.rb +42 -0
- data/lib/nrser/errors/nicer_error.rb +298 -72
- data/lib/nrser/errors/type_error.rb +46 -0
- data/lib/nrser/errors.rb +4 -53
- data/lib/nrser/ext/tree.rb +3 -0
- data/lib/nrser/functions/enumerable/associate.rb +6 -9
- data/lib/nrser/functions/enumerable/include_slice.rb +2 -3
- data/lib/nrser/functions/enumerable.rb +1 -3
- data/lib/nrser/functions/exception.rb +1 -1
- data/lib/nrser/functions/hash.rb +0 -6
- data/lib/nrser/functions/merge_by.rb +2 -2
- data/lib/nrser/functions/module/method_objects.rb +77 -0
- data/lib/nrser/functions/module.rb +1 -2
- data/lib/nrser/functions/open_struct.rb +25 -35
- data/lib/nrser/functions/proc.rb +1 -6
- data/lib/nrser/functions/string/looks_like.rb +32 -1
- data/lib/nrser/functions/string.rb +1 -40
- data/lib/nrser/functions/text/lines.rb +2 -1
- data/lib/nrser/functions.rb +0 -1
- data/lib/nrser/graph/tsorter.rb +41 -0
- data/lib/nrser/labs/core_ext/binding.rb +37 -0
- data/lib/nrser/labs/stash.rb +372 -0
- data/lib/nrser/{logging → log}/appender/sync.rb +3 -3
- data/lib/nrser/log/appender.rb +3 -0
- data/lib/nrser/{logging → log}/formatters/color.rb +47 -20
- data/lib/nrser/log/formatters/mixin.rb +270 -0
- data/lib/nrser/{logging → log}/formatters.rb +0 -0
- data/lib/nrser/log/logger.rb +229 -0
- data/lib/nrser/log/mixin.rb +56 -0
- data/lib/nrser/log.rb +723 -0
- data/lib/nrser/message.rb +24 -3
- data/lib/nrser/meta/source/location.rb +158 -0
- data/lib/nrser/meta.rb +1 -1
- data/lib/nrser/props/class_methods.rb +118 -0
- data/lib/nrser/props/immutable/hash.rb +111 -0
- data/lib/nrser/props/immutable/hash_variable.rb +82 -0
- data/lib/nrser/props/immutable/instance_variables.rb +48 -0
- data/lib/nrser/props/immutable/vector.rb +107 -0
- data/lib/nrser/props/instance_methods.rb +184 -0
- data/lib/nrser/props/metadata.rb +359 -0
- data/lib/nrser/props/mutable/instance_variables.rb +60 -0
- data/lib/nrser/props/mutable/stash.rb +199 -0
- data/lib/nrser/{meta/props → props}/prop.rb +217 -112
- data/lib/nrser/props/storage/instance_variable.rb +85 -0
- data/lib/nrser/props/storage/instance_variables.rb +67 -0
- data/lib/nrser/props/storage/key.rb +88 -0
- data/lib/nrser/props.rb +9 -0
- data/lib/nrser/refinements/sugar.rb +41 -0
- data/lib/nrser/refinements/types.rb +2 -2
- data/lib/nrser/refinements.rb +14 -16
- data/lib/nrser/rspex/example_group/describe_attribute.rb +24 -0
- data/lib/nrser/rspex/example_group/describe_called_with.rb +1 -6
- data/lib/nrser/rspex/example_group/{describe_use_case.rb → describe_case.rb} +6 -3
- data/lib/nrser/rspex/example_group/describe_class.rb +1 -0
- data/lib/nrser/rspex/example_group/describe_group.rb +29 -0
- data/lib/nrser/rspex/example_group/describe_instance_method.rb +2 -2
- data/lib/nrser/rspex/example_group/describe_message.rb +35 -0
- data/lib/nrser/rspex/example_group/describe_method.rb +23 -2
- data/lib/nrser/rspex/example_group/describe_module.rb +19 -0
- data/lib/nrser/rspex/example_group/describe_response_to.rb +32 -0
- data/lib/nrser/rspex/example_group/describe_section.rb +38 -0
- data/lib/nrser/rspex/example_group/describe_sent_to.rb +52 -0
- data/lib/nrser/rspex/example_group/describe_source_file.rb +49 -0
- data/lib/nrser/rspex/example_group/describe_spec_file.rb +41 -108
- data/lib/nrser/rspex/example_group/describe_when.rb +14 -7
- data/lib/nrser/rspex/example_group/describe_x.rb +39 -12
- data/lib/nrser/rspex/example_group/overrides.rb +66 -0
- data/lib/nrser/rspex/example_group.rb +20 -252
- data/lib/nrser/rspex/format.rb +83 -17
- data/lib/nrser/rspex.rb +4 -34
- data/lib/nrser/sugar/method_missing_forwarder.rb +50 -0
- data/lib/nrser/{env → sys/env}/path.rb +1 -2
- data/lib/nrser/{env.rb → sys/env.rb} +2 -1
- data/lib/nrser/sys.rb +5 -0
- data/lib/nrser/types/any.rb +36 -7
- data/lib/nrser/types/{array.rb → arrays.rb} +32 -81
- data/lib/nrser/types/attrs.rb +68 -15
- data/lib/nrser/types/booleans.rb +95 -34
- data/lib/nrser/types/bounded.rb +12 -10
- data/lib/nrser/types/combinators.rb +74 -37
- data/lib/nrser/types/errors/check_error.rb +86 -0
- data/lib/nrser/types/errors/from_string_error.rb +82 -0
- data/lib/nrser/types/factory.rb +91 -0
- data/lib/nrser/types/hashes.rb +171 -26
- data/lib/nrser/types/in.rb +25 -12
- data/lib/nrser/types/is.rb +50 -18
- data/lib/nrser/types/is_a.rb +52 -33
- data/lib/nrser/types/labels.rb +6 -33
- data/lib/nrser/types/maybe.rb +12 -4
- data/lib/nrser/types/nil.rb +24 -4
- data/lib/nrser/types/not.rb +6 -16
- data/lib/nrser/types/numbers.rb +94 -57
- data/lib/nrser/types/pairs.rb +57 -57
- data/lib/nrser/types/paths.rb +112 -133
- data/lib/nrser/types/responds.rb +64 -74
- data/lib/nrser/types/shape.rb +29 -24
- data/lib/nrser/types/strings.rb +25 -17
- data/lib/nrser/types/symbols.rb +19 -17
- data/lib/nrser/types/trees.rb +18 -70
- data/lib/nrser/types/tuples.rb +36 -40
- data/lib/nrser/types/type.rb +342 -91
- data/lib/nrser/types/when.rb +40 -18
- data/lib/nrser/types/where.rb +94 -9
- data/lib/nrser/types.rb +72 -63
- data/lib/nrser/version.rb +1 -1
- data/lib/nrser.rb +18 -18
- data/spec/lib/nrser/{functions/binding/template_spec.rb → core_ext/binding/erb_spec.rb} +5 -5
- data/spec/lib/nrser/{functions → core_ext}/enumerable/find_map_spec.rb +8 -6
- data/spec/lib/nrser/{refinements → core_ext}/hash_spec.rb +9 -22
- data/spec/lib/nrser/errors/abstract_method_error_spec.rb +12 -5
- data/spec/lib/nrser/functions/enumerable/{to_h_by_spec.rb → associate_spec.rb} +1 -1
- data/spec/lib/nrser/functions/merge_by_spec.rb +1 -1
- data/spec/lib/nrser/functions/tree/each_branch_spec.rb +3 -3
- data/spec/lib/nrser/functions/tree/transform_spec.rb +14 -15
- data/spec/lib/nrser/gem_ext/hamster/json_spec.rb +4 -0
- data/spec/lib/nrser/meta/source/location_spec.rb +86 -0
- data/spec/lib/nrser/props/immutable/hash_spec.rb +297 -0
- data/spec/lib/nrser/props/immutable/vector_spec.rb +296 -0
- data/spec/lib/nrser/{meta/props_spec.rb → props/original_props_spec.rb} +11 -16
- data/spec/lib/nrser/{meta/props → props}/to_and_from_data_spec.rb +10 -8
- data/spec/lib/nrser/refinements/array_spec.rb +2 -15
- data/spec/lib/nrser/refinements/erb_spec.rb +5 -7
- data/spec/lib/nrser/refinements/set_spec.rb +2 -15
- data/spec/lib/nrser/{env → sys/env}/path/insert_spec.rb +4 -2
- data/spec/lib/nrser/{env → sys/env}/path_spec.rb +4 -2
- data/spec/lib/nrser/types/array_spec.rb +8 -8
- data/spec/lib/nrser/types/paths_spec.rb +15 -18
- data/spec/spec_helper.rb +4 -0
- metadata +109 -69
- data/lib/nrser/ext/binding.rb +0 -36
- data/lib/nrser/ext/module.rb +0 -62
- data/lib/nrser/ext.rb +0 -8
- data/lib/nrser/functions/binding.rb +0 -76
- data/lib/nrser/functions/enumerable/map_keys.rb +0 -0
- data/lib/nrser/functions/enumerable/map_values.rb +0 -94
- data/lib/nrser/functions/hash/deep_merge.rb +0 -57
- data/lib/nrser/functions/hash/except_keys.rb +0 -44
- data/lib/nrser/functions/hash/slice_keys.rb +0 -43
- data/lib/nrser/functions/hash/stringify_keys.rb +0 -55
- data/lib/nrser/functions/hash/symbolize_keys.rb +0 -57
- data/lib/nrser/functions/hash/transform_keys.rb +0 -140
- data/lib/nrser/functions/module/methods.rb +0 -206
- data/lib/nrser/functions/module/source_locations.rb +0 -213
- data/lib/nrser/logging/appender.rb +0 -3
- data/lib/nrser/logging.rb +0 -353
- data/lib/nrser/meta/props/base.rb +0 -31
- data/lib/nrser/meta/props.rb +0 -357
- data/lib/nrser/refinements/array.rb +0 -133
- data/lib/nrser/refinements/binding.rb +0 -6
- data/lib/nrser/refinements/enumerator.rb +0 -5
- data/lib/nrser/refinements/exception.rb +0 -35
- data/lib/nrser/refinements/hash.rb +0 -150
- data/lib/nrser/refinements/module.rb +0 -5
- data/lib/nrser/refinements/object.rb +0 -42
- data/lib/nrser/refinements/open_struct.rb +0 -28
- data/lib/nrser/refinements/pathname.rb +0 -5
- data/lib/nrser/refinements/set.rb +0 -5
- data/lib/nrser/refinements/string.rb +0 -5
- data/lib/nrser/refinements/symbol.rb +0 -20
- data/lib/nrser/rspex/described.rb +0 -99
- data/spec/design/mapping_spec.rb +0 -42
- data/spec/lib/nrser/functions/hash_spec.rb +0 -41
- data/spec/lib/nrser/functions/string/truncate_spec.rb +0 -11
- data/spec/lib/nrser/refinements/truncate_spec.rb +0 -10
@@ -1,29 +1,13 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
1
4
|
# Requirements
|
2
5
|
# =======================================================================
|
3
6
|
|
4
|
-
# Stdlib
|
5
|
-
# -----------------------------------------------------------------------
|
6
|
-
|
7
|
-
# Deps
|
8
|
-
# -----------------------------------------------------------------------
|
9
|
-
|
10
7
|
# Project / Package
|
11
8
|
# -----------------------------------------------------------------------
|
12
|
-
require 'nrser/types/type'
|
13
|
-
require 'nrser/types/is_a'
|
14
|
-
|
15
|
-
|
16
|
-
# Refinements
|
17
|
-
# =======================================================================
|
18
|
-
|
19
|
-
require 'nrser/refinements'
|
20
|
-
using NRSER
|
21
9
|
|
22
|
-
|
23
|
-
# Declarations
|
24
|
-
# =======================================================================
|
25
|
-
|
26
|
-
module NRSER; end
|
10
|
+
require_relative './is_a'
|
27
11
|
|
28
12
|
|
29
13
|
# Definitions
|
@@ -36,25 +20,16 @@ module NRSER::Types
|
|
36
20
|
# does is not recognized as an encoding format (as of writing, JSON is
|
37
21
|
# the only format we attempt to detect).
|
38
22
|
#
|
39
|
-
# Splits
|
23
|
+
# Splits
|
40
24
|
DEFAULT_SPLIT_WITH = /\,\s*/m
|
41
25
|
|
42
|
-
attr_reader :item_type
|
43
|
-
|
44
26
|
def initialize split_with: DEFAULT_SPLIT_WITH, **options
|
45
27
|
super ::Array, **options
|
46
28
|
@split_with = split_with
|
47
29
|
end
|
48
30
|
|
49
31
|
|
50
|
-
def
|
51
|
-
self.class.short_name
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
def item_type
|
56
|
-
NRSER::Types.any
|
57
|
-
end
|
32
|
+
def item_type; NRSER::Types.any; end
|
58
33
|
|
59
34
|
|
60
35
|
# Called on an array of string items that have been split
|
@@ -73,40 +48,29 @@ module NRSER::Types
|
|
73
48
|
end
|
74
49
|
|
75
50
|
|
76
|
-
def
|
77
|
-
# Use custom {@from_s} if we have one.
|
78
|
-
return check( @from_s.call s ) unless @from_s.nil?
|
79
|
-
|
51
|
+
def custom_from_s string
|
80
52
|
# Does it looks like a JSON array?
|
81
|
-
if NRSER.looks_like_json_array?
|
53
|
+
if NRSER.looks_like_json_array? string
|
82
54
|
# It does! Load it
|
83
55
|
begin
|
84
|
-
|
56
|
+
return JSON.load( string )
|
85
57
|
rescue
|
86
58
|
# pass - if we failed to load as JSON, it may just not be JSON, and
|
87
59
|
# we can try the split approach below.
|
88
|
-
else
|
89
|
-
# Check value and return. If we fail the check here let the error
|
90
|
-
# bubble up
|
91
|
-
return check array
|
92
60
|
end
|
93
61
|
end
|
94
62
|
|
95
63
|
# Split it with the splitter and check that
|
96
|
-
|
64
|
+
items_from_strings( string.split( @split_with ) )
|
97
65
|
end
|
98
66
|
|
99
67
|
end # ArrayType
|
100
68
|
|
101
69
|
|
102
|
-
# Static instance that is satisfied by anything that is an {Array}.
|
103
|
-
ARRAY = ArrayType.new.freeze
|
104
|
-
|
105
|
-
|
106
70
|
# Type for arrays where every entry satisfies a specific type.
|
107
71
|
#
|
108
72
|
# Broken out from {ArrayType} so that {TupleType} can inherit from
|
109
|
-
# {ArrayType} and get share it's string handling functionality without
|
73
|
+
# {ArrayType} and get share it's string handling functionality without
|
110
74
|
# receiving the entry type stuff (which it handles differently).
|
111
75
|
#
|
112
76
|
class ArrayOfType < ArrayType
|
@@ -135,12 +99,12 @@ module NRSER::Types
|
|
135
99
|
# Instance Methods
|
136
100
|
# ======================================================================
|
137
101
|
|
138
|
-
def
|
139
|
-
"#{ super() }<#{
|
102
|
+
def explain
|
103
|
+
"#{ super() }<#{ item_type.explain }>"
|
140
104
|
end
|
141
105
|
|
142
106
|
|
143
|
-
def test value
|
107
|
+
def test? value
|
144
108
|
# Check the super method first, which will test if `value` is an Array
|
145
109
|
# instance, and return `false` if it's not.
|
146
110
|
return false unless super( value )
|
@@ -156,7 +120,7 @@ module NRSER::Types
|
|
156
120
|
# @return [Boolean]
|
157
121
|
#
|
158
122
|
def has_from_s?
|
159
|
-
@item_type.has_from_s?
|
123
|
+
@from_s || @item_type.has_from_s?
|
160
124
|
end
|
161
125
|
|
162
126
|
|
@@ -168,7 +132,7 @@ module NRSER::Types
|
|
168
132
|
# @todo
|
169
133
|
# I'm not even sure why this is implemented... was it used somewhere?
|
170
134
|
#
|
171
|
-
# It doesn't seems too well thought out... seems like the reality of
|
135
|
+
# It doesn't seems too well thought out... seems like the reality of
|
172
136
|
# comparing types is much more complicated?
|
173
137
|
#
|
174
138
|
def == other
|
@@ -180,35 +144,22 @@ module NRSER::Types
|
|
180
144
|
end # class ArrayOfType
|
181
145
|
|
182
146
|
|
183
|
-
#
|
184
|
-
# ========================================================================
|
147
|
+
# {NRSER::Types::ArrayType} / {NRSER::Types::ArrayOfType} factory function.
|
185
148
|
#
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
else
|
202
|
-
ArrayType.new **options
|
203
|
-
end
|
204
|
-
else
|
205
|
-
ArrayOfType.new item_type, **options
|
206
|
-
end
|
207
|
-
end # #array
|
208
|
-
|
209
|
-
alias_method :list, :array
|
210
|
-
|
211
|
-
end # class << self (Eigenclass)
|
212
|
-
|
149
|
+
# @param [Type | Object] item_type
|
150
|
+
# Optional type of items.
|
151
|
+
#
|
152
|
+
# @return [NRSER::Types::Type]
|
153
|
+
#
|
154
|
+
def_factory(
|
155
|
+
:array,
|
156
|
+
aliases: [:list],
|
157
|
+
) do |item_type = any, **options|
|
158
|
+
if item_type == any
|
159
|
+
ArrayType.new **options
|
160
|
+
else
|
161
|
+
ArrayOfType.new item_type, **options
|
162
|
+
end
|
163
|
+
end # #array
|
213
164
|
|
214
165
|
end # NRSER::Types
|
data/lib/nrser/types/attrs.rb
CHANGED
@@ -1,11 +1,37 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'nrser/types/combinators'
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
4
3
|
|
5
|
-
|
4
|
+
|
5
|
+
# Requirements
|
6
|
+
# ========================================================================
|
7
|
+
|
8
|
+
# Project / Package
|
9
|
+
# ------------------------------------------------------------------------
|
10
|
+
|
11
|
+
require 'nrser/core_ext/hash'
|
12
|
+
|
13
|
+
require_relative './type'
|
14
|
+
require_relative './combinators'
|
15
|
+
require_relative './is'
|
16
|
+
|
17
|
+
|
18
|
+
# Definitions
|
19
|
+
# ========================================================================
|
6
20
|
|
7
21
|
module NRSER::Types
|
8
|
-
|
22
|
+
|
23
|
+
# Specify types for value attributes.
|
24
|
+
#
|
25
|
+
class AttrsType < NRSER::Types::Type
|
26
|
+
|
27
|
+
# Construct an `AttrsType`.
|
28
|
+
#
|
29
|
+
# @param [Hash<Symbol, TYPE>] attrs
|
30
|
+
# Map of attribute names to their types (`TYPE` values will be passed
|
31
|
+
# through {NRSER::Types.make} to get a type instance).
|
32
|
+
#
|
33
|
+
# May not be empty.
|
34
|
+
#
|
9
35
|
def initialize attrs, **options
|
10
36
|
super **options
|
11
37
|
|
@@ -14,12 +40,15 @@ module NRSER::Types
|
|
14
40
|
"Must provide at least one attribute name/type pair"
|
15
41
|
end
|
16
42
|
|
17
|
-
@attrs = NRSER.
|
18
|
-
NRSER::Types.make type
|
19
|
-
}
|
43
|
+
@attrs = attrs.transform_values &NRSER::Types.maker
|
20
44
|
end
|
21
45
|
|
22
|
-
|
46
|
+
|
47
|
+
# @see NRSER::Types::Type#explain
|
48
|
+
#
|
49
|
+
# @return [String]
|
50
|
+
#
|
51
|
+
def explain
|
23
52
|
attrs_str = @attrs.map { |name, type|
|
24
53
|
"##{ name }#{ RESPONDS_WITH }#{ type.name }"
|
25
54
|
}.join(', ')
|
@@ -31,12 +60,19 @@ module NRSER::Types
|
|
31
60
|
end
|
32
61
|
end
|
33
62
|
|
34
|
-
|
63
|
+
|
64
|
+
# @see NRSER::Types::Type#test
|
65
|
+
#
|
66
|
+
# @return [Boolean]
|
67
|
+
#
|
68
|
+
def test? value
|
35
69
|
@attrs.all? { |name, type|
|
36
|
-
value.respond_to?(name) &&
|
70
|
+
value.respond_to?( name ) &&
|
71
|
+
type.test?( value.method( name ).call )
|
37
72
|
}
|
38
73
|
end
|
39
|
-
|
74
|
+
|
75
|
+
end # AttrsType
|
40
76
|
|
41
77
|
|
42
78
|
# @!group Type Factory Functions
|
@@ -46,8 +82,20 @@ module NRSER::Types
|
|
46
82
|
# @example Type where first element of an Enumerable is a String
|
47
83
|
# string_first = intersection Enumerable, attrs(first: String)
|
48
84
|
#
|
49
|
-
def_factory :attrs do |
|
50
|
-
|
85
|
+
def_factory :attrs do |*args|
|
86
|
+
case args.length
|
87
|
+
when 0
|
88
|
+
raise NRSER::ArgumentError.new \
|
89
|
+
"requires at least one argument"
|
90
|
+
when 1
|
91
|
+
attrs = args[0]
|
92
|
+
options = {}
|
93
|
+
when 2
|
94
|
+
attrs = args[0]
|
95
|
+
options = args[1]
|
96
|
+
end
|
97
|
+
|
98
|
+
AttrsType.new attrs, **options
|
51
99
|
end
|
52
100
|
|
53
101
|
|
@@ -114,11 +162,16 @@ module NRSER::Types
|
|
114
162
|
case args[0]
|
115
163
|
when ::Integer
|
116
164
|
# It's just a length
|
165
|
+
return attrs(
|
166
|
+
{ length: is( non_neg_int.check!( args[0] ) ) },
|
167
|
+
**options
|
168
|
+
)
|
169
|
+
|
117
170
|
bounds[:min] = bounds[:max] = non_neg_int.check args[0]
|
118
171
|
|
119
172
|
when ::Hash
|
120
173
|
# It's keyword args
|
121
|
-
kwds =
|
174
|
+
kwds = args[0].sym_keys
|
122
175
|
|
123
176
|
# Pull any :min and :max in the keywords
|
124
177
|
bounds[:min] = kwds.delete :min
|
data/lib/nrser/types/booleans.rb
CHANGED
@@ -1,47 +1,108 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Need truthy and falsy parse values
|
5
|
+
require 'nrser/functions/object/truthy'
|
6
|
+
|
7
|
+
require_relative './type'
|
8
|
+
require_relative './is'
|
9
|
+
require_relative './combinators'
|
5
10
|
|
6
|
-
using NRSER
|
7
11
|
|
8
12
|
module NRSER::Types
|
9
|
-
# booleans
|
10
|
-
# ========
|
11
|
-
|
12
|
-
TRUE = is true, name: 'true', from_s: ->(string) {
|
13
|
-
if ['true', 't', '1', 'yes', 'y', 'on'].include? string.downcase
|
14
|
-
true
|
15
|
-
else
|
16
|
-
raise TypeError, "can not convert to true: #{ string.inspect }"
|
17
|
-
end
|
18
|
-
}
|
19
|
-
|
20
|
-
def self.true
|
21
|
-
TRUE
|
22
|
-
end
|
23
13
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
14
|
+
# Abstract base class for {TrueType} and {FalseType}.
|
15
|
+
#
|
16
|
+
class BooleanType < Is
|
17
|
+
|
18
|
+
# Instantiate a new `BooleanType`.
|
19
|
+
#
|
20
|
+
def initialize value, **options
|
21
|
+
# Check it's a boolean
|
22
|
+
unless true.equal?( value ) || false.equal?( value )
|
23
|
+
raise ArgumentError.new \
|
24
|
+
"`value` arg must be `true` or `false`, found #{ value.inspect }"
|
25
|
+
end
|
26
|
+
|
27
|
+
super value, **options
|
28
|
+
end # #initialize
|
29
|
+
|
30
|
+
|
31
|
+
protected
|
32
|
+
# ========================================================================
|
33
|
+
|
34
|
+
def custom_from_s string
|
35
|
+
return value if self::STRINGS.include?( string.downcase )
|
36
|
+
|
37
|
+
raise NRSER::Types::FromStringError.new \
|
38
|
+
type: self,
|
39
|
+
string: string,
|
40
|
+
binding: binding,
|
41
|
+
details: -> {
|
42
|
+
<<~END
|
43
|
+
Down-cased `string` must be one of:
|
44
|
+
|
45
|
+
<%= self::STRINGS.to_a %>
|
46
|
+
END
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
public # end protected *****************************************************
|
51
|
+
|
52
|
+
end # class TrueType
|
53
|
+
|
54
|
+
|
55
|
+
# A type for only the `true`.
|
56
|
+
#
|
57
|
+
# Provides a {#custom_from_s} to load from CLI options and ENV var-like
|
58
|
+
# string values.
|
59
|
+
#
|
60
|
+
class TrueType < BooleanType
|
61
|
+
|
62
|
+
STRINGS = NRSER::TRUTHY_STRINGS
|
63
|
+
|
64
|
+
# Instantiate a new `TrueType`.
|
65
|
+
#
|
66
|
+
def initialize **options
|
67
|
+
super true, **options
|
68
|
+
end # #initialize
|
69
|
+
|
70
|
+
end # class TrueType
|
31
71
|
|
32
|
-
|
33
|
-
|
72
|
+
|
73
|
+
# A type for only `false`.
|
74
|
+
#
|
75
|
+
# Provides a {#custom_from_s} to load from CLI options and ENV var-like
|
76
|
+
# string values.
|
77
|
+
#
|
78
|
+
class FalseType < BooleanType
|
79
|
+
|
80
|
+
STRINGS = NRSER::FALSY_STRINGS
|
81
|
+
|
82
|
+
# Instantiate a new `TrueType`.
|
83
|
+
#
|
84
|
+
def initialize **options
|
85
|
+
super false, **options
|
86
|
+
end # #initialize
|
87
|
+
|
88
|
+
end # class FalseType
|
89
|
+
|
90
|
+
|
91
|
+
def_factory :true do |**options|
|
92
|
+
TrueType.new **options
|
34
93
|
end
|
35
94
|
|
36
|
-
BOOL = union TRUE, FALSE
|
37
95
|
|
38
|
-
|
39
|
-
|
40
|
-
BOOL
|
96
|
+
def_factory :false do |**options|
|
97
|
+
FalseType.new **options
|
41
98
|
end
|
42
99
|
|
43
|
-
|
44
|
-
|
100
|
+
|
101
|
+
def_factory(
|
102
|
+
:bool,
|
103
|
+
aliases: [ :boolean ],
|
104
|
+
) do |**options|
|
105
|
+
union self.true, self.false, **options
|
45
106
|
end
|
46
107
|
|
47
108
|
end # NRSER::Types
|
data/lib/nrser/types/bounded.rb
CHANGED
@@ -6,15 +6,17 @@ using NRSER
|
|
6
6
|
module NRSER::Types
|
7
7
|
class Bounded < NRSER::Types::Type
|
8
8
|
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
9
|
+
# Minimum value.
|
10
|
+
#
|
11
|
+
# @return [Number]
|
12
|
+
#
|
12
13
|
attr_reader :min
|
13
14
|
|
14
15
|
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
16
|
+
# Minimum value.
|
17
|
+
#
|
18
|
+
# @return [Number]
|
19
|
+
#
|
18
20
|
attr_reader :max
|
19
21
|
|
20
22
|
|
@@ -27,13 +29,13 @@ module NRSER::Types
|
|
27
29
|
@max = max
|
28
30
|
end
|
29
31
|
|
30
|
-
def test value
|
32
|
+
def test? value
|
31
33
|
return false if @min && value < @min
|
32
34
|
return false if @max && value > @max
|
33
35
|
true
|
34
36
|
end
|
35
37
|
|
36
|
-
def
|
38
|
+
def explain
|
37
39
|
attrs_str = ['min', 'max'].map {|name|
|
38
40
|
[name, instance_variable_get("@#{ name }")]
|
39
41
|
}.reject {|name, value|
|
@@ -42,12 +44,12 @@ module NRSER::Types
|
|
42
44
|
"#{ name }=#{ value }"
|
43
45
|
}.join(', ')
|
44
46
|
|
45
|
-
"#{ self.class.
|
47
|
+
"#{ self.class.demod_name }<#{ attrs_str }>"
|
46
48
|
end
|
47
49
|
|
48
50
|
end # Bounded
|
49
51
|
|
50
|
-
|
52
|
+
def_factory :bounded do |**options|
|
51
53
|
Bounded.new **options
|
52
54
|
end
|
53
55
|
|
@@ -1,31 +1,37 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require 'nrser/refinements'
|
5
4
|
require 'nrser/types/type'
|
6
5
|
|
7
|
-
using NRSER
|
8
|
-
|
9
6
|
# base class for Union and Intersection which combine over a set of types.
|
10
7
|
module NRSER::Types
|
8
|
+
|
9
|
+
# Abstract base class for logically combining types to create new ones.
|
10
|
+
#
|
11
11
|
class Combinator < NRSER::Types::Type
|
12
|
+
|
13
|
+
# The parametrized types, in the order they will be tested.
|
14
|
+
#
|
15
|
+
# @return [Array<NRSER::Types::Type>]
|
16
|
+
#
|
12
17
|
attr_reader :types
|
13
18
|
|
14
19
|
|
15
20
|
def initialize *types, **options
|
16
21
|
super **options
|
17
|
-
@types = types.map {|type| NRSER::Types.make type}
|
22
|
+
@types = types.map { |type| NRSER::Types.make type }
|
18
23
|
end
|
19
24
|
|
20
25
|
|
21
|
-
def
|
26
|
+
def explain
|
22
27
|
if self.class::JOIN_SYMBOL
|
23
|
-
NRSER::Types::L_PAREN +
|
24
|
-
@types.map { |type| type.
|
28
|
+
NRSER::Types::L_PAREN + # ' ' +
|
29
|
+
@types.map { |type| type.explain }.join( self.class::JOIN_SYMBOL ) +
|
30
|
+
# ' ' +
|
25
31
|
NRSER::Types::R_PAREN
|
26
32
|
else
|
27
|
-
"#{ self.class.
|
28
|
-
|
33
|
+
"#{ self.class.demod_name }<" +
|
34
|
+
@types.map { |type| type.explain }.join( ',' ) +
|
29
35
|
">"
|
30
36
|
end
|
31
37
|
end
|
@@ -59,7 +65,7 @@ module NRSER::Types
|
|
59
65
|
# @raise [TypeError]
|
60
66
|
# See write up above.
|
61
67
|
#
|
62
|
-
def
|
68
|
+
def custom_from_s s
|
63
69
|
unless @from_s.nil?
|
64
70
|
return check @from_s.call( s )
|
65
71
|
end
|
@@ -92,10 +98,39 @@ module NRSER::Types
|
|
92
98
|
# @return [Boolean]
|
93
99
|
#
|
94
100
|
def has_from_s?
|
95
|
-
|
101
|
+
!@from_s.nil? || @types.any? { |type| type.has_from_s? }
|
96
102
|
end # has_from_s
|
97
103
|
|
98
104
|
|
105
|
+
def has_from_data?
|
106
|
+
@types.any? { |type| type.has_from_data? }
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
# Overridden to
|
111
|
+
def from_data data
|
112
|
+
unless has_from_data?
|
113
|
+
raise NoMethodError, "#from_data not defined"
|
114
|
+
end
|
115
|
+
|
116
|
+
errors = []
|
117
|
+
|
118
|
+
types.each do |type|
|
119
|
+
if type.has_from_data?
|
120
|
+
begin
|
121
|
+
return check!( type.from_data data )
|
122
|
+
rescue Exception => error
|
123
|
+
errors << error
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
raise NRSER::MultipleErrors.new \
|
129
|
+
errors,
|
130
|
+
headline: "No type successfully loaded data"
|
131
|
+
end
|
132
|
+
|
133
|
+
|
99
134
|
# Overridden to delegate functionality to the combined types:
|
100
135
|
#
|
101
136
|
# A combinator can convert a value to data if *any* of it's types can.
|
@@ -120,7 +155,7 @@ module NRSER::Types
|
|
120
155
|
#
|
121
156
|
def to_data value
|
122
157
|
@types.each { |type|
|
123
|
-
if type.
|
158
|
+
if type.has_to_data?
|
124
159
|
return type.to_data value
|
125
160
|
end
|
126
161
|
}
|
@@ -134,57 +169,59 @@ module NRSER::Types
|
|
134
169
|
other.class == self.class && other.types == @types
|
135
170
|
)
|
136
171
|
end
|
137
|
-
|
172
|
+
|
173
|
+
end # class Combinator
|
174
|
+
|
138
175
|
|
139
176
|
class Union < Combinator
|
140
|
-
JOIN_SYMBOL = ' ⋁ '
|
177
|
+
JOIN_SYMBOL = ' | ' # ' ⋁ '
|
141
178
|
|
142
|
-
def test value
|
143
|
-
@types.any? {|type| type.test value}
|
179
|
+
def test? value
|
180
|
+
@types.any? { |type| type.test value }
|
144
181
|
end
|
145
|
-
end # Union
|
182
|
+
end # class Union
|
183
|
+
|
146
184
|
|
147
185
|
# match any of the types
|
148
|
-
|
149
|
-
|
186
|
+
def_factory(
|
187
|
+
:union,
|
188
|
+
aliases: [:one_of, :or],
|
189
|
+
) do |*types, **options|
|
190
|
+
Union.new *types, **options
|
150
191
|
end
|
151
192
|
|
152
|
-
singleton_class.send :alias_method, :one_of, :union
|
153
|
-
singleton_class.send :alias_method, :or, :union
|
154
193
|
|
155
194
|
class Intersection < Combinator
|
156
|
-
|
157
|
-
JOIN_SYMBOL = ' ⋀ '
|
195
|
+
JOIN_SYMBOL = ' & ' # ' ⋀ '
|
158
196
|
|
159
|
-
def test value
|
160
|
-
@types.all? { |type| type.test value}
|
197
|
+
def test? value
|
198
|
+
@types.all? { |type| type.test? value }
|
161
199
|
end
|
162
|
-
end
|
200
|
+
end # class Intersection
|
201
|
+
|
163
202
|
|
164
203
|
# match all of the types
|
165
|
-
|
204
|
+
def_factory(
|
205
|
+
:intersection,
|
206
|
+
aliases: [:all_of, :and],
|
207
|
+
) do |*types, **options|
|
166
208
|
Intersection.new *types, **options
|
167
209
|
end
|
168
210
|
|
169
|
-
singleton_class.send :alias_method, :all_of, :intersection
|
170
|
-
singleton_class.send :alias_method, :and, :intersection
|
171
|
-
|
172
211
|
|
173
212
|
class XOR < Combinator
|
174
213
|
JOIN_SYMBOL = ' ⊕ '
|
175
214
|
|
176
|
-
def test value
|
215
|
+
def test? value
|
177
216
|
@types.count { |type| type === value } == 1
|
178
217
|
end
|
179
|
-
|
180
|
-
# def default_name
|
181
|
-
# '⊕'
|
182
|
-
# "( #{ @types.map { |t| t.name }.join ' ⊕ ' } )"
|
183
|
-
# end
|
184
218
|
end
|
185
219
|
|
186
220
|
|
187
|
-
|
221
|
+
def_factory(
|
222
|
+
:xor,
|
223
|
+
aliases: [ :exclusive_or, :only_one_of ],
|
224
|
+
) do |*types, **options|
|
188
225
|
XOR.new *types, **options
|
189
226
|
end
|
190
227
|
|