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.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/lib/nrser/char/alpha_numeric_sub.rb +9 -19
  3. data/lib/nrser/char/special.rb +5 -5
  4. data/lib/nrser/core_ext/array.rb +36 -13
  5. data/lib/nrser/core_ext/enumerable.rb +1 -0
  6. data/lib/nrser/core_ext/enumerable/find_map.rb +1 -1
  7. data/lib/nrser/core_ext/hash/bury.rb +3 -0
  8. data/lib/nrser/core_ext/hash/extract_values_at.rb +2 -2
  9. data/lib/nrser/core_ext/method/full_name.rb +1 -1
  10. data/lib/nrser/core_ext/module/method_objects.rb +1 -1
  11. data/lib/nrser/core_ext/module/source_locations.rb +27 -15
  12. data/lib/nrser/core_ext/object/lazy_var.rb +1 -1
  13. data/lib/nrser/core_ext/pathname.rb +67 -12
  14. data/lib/nrser/core_ext/pathname/subpath.rb +86 -0
  15. data/lib/nrser/core_ext/string.rb +28 -1
  16. data/lib/nrser/core_ext/symbol.rb +11 -12
  17. data/lib/nrser/errors/README.md +154 -0
  18. data/lib/nrser/errors/attr_error.rb +146 -53
  19. data/lib/nrser/errors/count_error.rb +61 -12
  20. data/lib/nrser/errors/nicer_error.rb +42 -71
  21. data/lib/nrser/errors/value_error.rb +53 -58
  22. data/lib/nrser/functions.rb +0 -2
  23. data/lib/nrser/functions/enumerable.rb +5 -17
  24. data/lib/nrser/functions/enumerable/associate.rb +14 -5
  25. data/lib/nrser/functions/enumerable/find_all_map.rb +1 -1
  26. data/lib/nrser/functions/enumerable/include_slice/array_include_slice.rb +1 -1
  27. data/lib/nrser/functions/hash/bury.rb +2 -12
  28. data/lib/nrser/functions/merge_by.rb +2 -2
  29. data/lib/nrser/functions/module/method_objects.rb +2 -2
  30. data/lib/nrser/functions/path.rb +185 -165
  31. data/lib/nrser/functions/path/normalized.rb +84 -0
  32. data/lib/nrser/functions/string.rb +4 -4
  33. data/lib/nrser/functions/text/README.md +4 -0
  34. data/lib/nrser/functions/text/format.rb +53 -0
  35. data/lib/nrser/functions/text/indentation.rb +6 -6
  36. data/lib/nrser/functions/text/word_wrap.rb +2 -2
  37. data/lib/nrser/functions/tree/map_leaves.rb +3 -3
  38. data/lib/nrser/functions/tree/map_tree.rb +2 -2
  39. data/lib/nrser/functions/tree/transform.rb +1 -18
  40. data/lib/nrser/gem_ext/README.md +4 -0
  41. data/lib/nrser/labs/README.md +8 -0
  42. data/lib/nrser/labs/config.rb +163 -0
  43. data/lib/nrser/labs/i8.rb +49 -159
  44. data/lib/nrser/labs/i8/struct.rb +167 -0
  45. data/lib/nrser/labs/i8/struct/hash.rb +140 -0
  46. data/lib/nrser/labs/i8/struct/vector.rb +149 -0
  47. data/lib/nrser/labs/i8/surjection.rb +211 -0
  48. data/lib/nrser/labs/lots/consumer.rb +19 -0
  49. data/lib/nrser/labs/lots/parser.rb +21 -1
  50. data/lib/nrser/labs/stash.rb +4 -4
  51. data/lib/nrser/log.rb +25 -21
  52. data/lib/nrser/log/appender/sync.rb +15 -11
  53. data/lib/nrser/log/formatters/color.rb +0 -3
  54. data/lib/nrser/log/formatters/mixin.rb +4 -4
  55. data/lib/nrser/log/logger.rb +54 -6
  56. data/lib/nrser/log/mixin.rb +2 -1
  57. data/lib/nrser/log/plugin.rb +6 -6
  58. data/lib/nrser/log/types.rb +46 -29
  59. data/lib/nrser/mean_streak.rb +0 -8
  60. data/lib/nrser/mean_streak/document.rb +1 -4
  61. data/lib/nrser/message.rb +3 -3
  62. data/lib/nrser/meta/README.md +4 -0
  63. data/lib/nrser/meta/lazy_attr.rb +2 -2
  64. data/lib/nrser/meta/source/location.rb +1 -1
  65. data/lib/nrser/props.rb +34 -3
  66. data/lib/nrser/props/class_methods.rb +2 -1
  67. data/lib/nrser/props/instance_methods.rb +9 -9
  68. data/lib/nrser/props/metadata.rb +4 -12
  69. data/lib/nrser/props/mutable/stash.rb +5 -2
  70. data/lib/nrser/props/prop.rb +10 -19
  71. data/lib/nrser/rspex.rb +1 -20
  72. data/lib/nrser/rspex/example_group/describe_attribute.rb +3 -0
  73. data/lib/nrser/rspex/example_group/describe_called_with.rb +9 -4
  74. data/lib/nrser/rspex/example_group/describe_case.rb +1 -0
  75. data/lib/nrser/rspex/example_group/describe_class.rb +2 -0
  76. data/lib/nrser/rspex/example_group/describe_group.rb +1 -1
  77. data/lib/nrser/rspex/example_group/describe_instance.rb +3 -1
  78. data/lib/nrser/rspex/example_group/describe_message.rb +1 -1
  79. data/lib/nrser/rspex/example_group/describe_method.rb +64 -30
  80. data/lib/nrser/rspex/example_group/describe_response_to.rb +1 -1
  81. data/lib/nrser/rspex/example_group/describe_section.rb +4 -1
  82. data/lib/nrser/rspex/example_group/describe_sent_to.rb +1 -1
  83. data/lib/nrser/rspex/example_group/describe_setup.rb +1 -0
  84. data/lib/nrser/rspex/example_group/describe_source_file.rb +1 -1
  85. data/lib/nrser/rspex/example_group/describe_spec_file.rb +4 -2
  86. data/lib/nrser/rspex/example_group/describe_when.rb +2 -1
  87. data/lib/nrser/rspex/example_group/describe_x.rb +5 -5
  88. data/lib/nrser/rspex/format.rb +0 -15
  89. data/lib/nrser/sugar/method_missing_forwarder.rb +3 -3
  90. data/lib/nrser/sys/env/path.rb +2 -28
  91. data/lib/nrser/types.rb +63 -12
  92. data/lib/nrser/types/README.md +76 -0
  93. data/lib/nrser/types/arrays.rb +192 -137
  94. data/lib/nrser/types/attributes.rb +269 -0
  95. data/lib/nrser/types/booleans.rb +134 -83
  96. data/lib/nrser/types/bounded.rb +110 -47
  97. data/lib/nrser/types/collections.rb +119 -0
  98. data/lib/nrser/types/combinators.rb +283 -196
  99. data/lib/nrser/types/doc/display_table.md +66 -0
  100. data/lib/nrser/types/eqiuvalent.rb +91 -0
  101. data/lib/nrser/types/errors/check_error.rb +5 -11
  102. data/lib/nrser/types/errors/from_string_error.rb +3 -3
  103. data/lib/nrser/types/factory.rb +287 -20
  104. data/lib/nrser/types/hashes.rb +227 -179
  105. data/lib/nrser/types/in.rb +73 -36
  106. data/lib/nrser/types/is.rb +67 -60
  107. data/lib/nrser/types/is_a.rb +141 -84
  108. data/lib/nrser/types/labels.rb +45 -16
  109. data/lib/nrser/types/maybe.rb +6 -3
  110. data/lib/nrser/types/nil.rb +64 -27
  111. data/lib/nrser/types/not.rb +92 -34
  112. data/lib/nrser/types/numbers.rb +224 -169
  113. data/lib/nrser/types/pairs.rb +113 -89
  114. data/lib/nrser/types/paths.rb +250 -137
  115. data/lib/nrser/types/responds.rb +167 -89
  116. data/lib/nrser/types/selector.rb +234 -0
  117. data/lib/nrser/types/shape.rb +136 -65
  118. data/lib/nrser/types/strings.rb +189 -63
  119. data/lib/nrser/types/symbols.rb +83 -33
  120. data/lib/nrser/types/top.rb +89 -0
  121. data/lib/nrser/types/tuples.rb +134 -98
  122. data/lib/nrser/types/type.rb +617 -505
  123. data/lib/nrser/types/when.rb +123 -98
  124. data/lib/nrser/types/where.rb +182 -91
  125. data/lib/nrser/version.rb +1 -1
  126. data/spec/lib/nrser/core_ext/pathname/subpath_spec.rb +22 -0
  127. data/spec/lib/nrser/errors/attr_error_spec.rb +68 -0
  128. data/spec/lib/nrser/errors/count_error_spec.rb +69 -0
  129. data/spec/lib/nrser/functions/path/normalize_path_spec.rb +35 -0
  130. data/spec/lib/nrser/functions/tree/map_tree_spec.rb +74 -96
  131. data/spec/lib/nrser/functions/tree/transform_spec.rb +11 -11
  132. data/spec/lib/nrser/labs/config_spec.rb +22 -0
  133. data/spec/lib/nrser/labs/i8/struct_spec.rb +39 -0
  134. data/spec/lib/nrser/types/display_spec.rb +50 -0
  135. data/spec/lib/nrser/types/paths_spec.rb +16 -10
  136. data/spec/lib/nrser/types/selector_spec.rb +125 -0
  137. data/spec/spec_helper.rb +4 -5
  138. metadata +105 -22
  139. data/lib/nrser/types/any.rb +0 -41
  140. data/lib/nrser/types/attrs.rb +0 -213
  141. data/lib/nrser/types/trees.rb +0 -42
@@ -2,79 +2,150 @@
2
2
  # encoding: UTF-8
3
3
 
4
4
 
5
+ # Requirements
6
+ # ========================================================================
7
+
8
+ # Project / Package
9
+ # ------------------------------------------------------------------------
10
+
11
+ require_relative './type'
12
+
13
+
14
+ # Namespace
15
+ # ========================================================================
16
+
17
+ module NRSER
18
+ module Types
19
+
20
+
5
21
  # Definitions
6
22
  # =======================================================================
7
23
 
8
- module NRSER::Types
24
+ # Create a {Shape} type that parameterizes {#pairs} of object keys and {Type}
25
+ # values.
26
+ #
27
+ # Members of the type are values `v` for which for all keys `k` and
28
+ # paired value types `t_k` `v[k]` is a member of `t_k`:
29
+ #
30
+ # shape.pairs.all? { |k, t_k| t_k.test? v[k] }
31
+ #
32
+ # @note
33
+ # Construct shape types using the {.Shape} factory.
34
+ #
35
+ class Shape < Type
9
36
 
10
- class Shape < Type
11
-
12
-
13
- # Attributes
14
- # ========================================================================
15
-
16
- # TODO document `pairs` attribute.
17
- #
18
- # @return [Hash]
19
- #
20
- attr_reader :pairs
21
-
22
-
23
- # Constructor
24
- # ======================================================================
25
-
26
- # Instantiate a new `NRSER::Types::Shape`.
27
- def initialize pairs, **options
28
- super **options
29
- @pairs = pairs.map { |k, v|
30
- [k, NRSER::Types.make( v )]
31
- }.to_h.freeze
32
- end # #initialize
33
-
34
-
35
- # Instance Methods
36
- # ======================================================================
37
-
38
- def test? value
39
- begin
40
- @pairs.all? { |k, v|
41
- v === value[k]
42
- }
43
- rescue
44
- false
45
- end
37
+ # Attributes
38
+ # ========================================================================
39
+
40
+ # TODO document `pairs` attribute.
41
+ #
42
+ # @return [Hash]
43
+ #
44
+ attr_reader :pairs
45
+
46
+
47
+ # Constructor
48
+ # ======================================================================
49
+
50
+ # Instantiate a new `NRSER::Types::Shape`.
51
+ def initialize pairs, **options
52
+ super **options
53
+ @pairs = pairs.map { |k, v|
54
+ [k, NRSER::Types.make( v )]
55
+ }.to_h.freeze
56
+ end # #initialize
57
+
58
+
59
+ # Instance Methods
60
+ # ======================================================================
61
+
62
+ def test? value
63
+ begin
64
+ @pairs.all? { |k, v| v === value[k] }
65
+ rescue
66
+ false
46
67
  end
47
-
48
- def explain
49
- inner = @pairs.map { |k, v|
50
- "[#{ k.inspect }]→#{ v.name }"
51
- }.join( ", " )
52
-
53
- if @pairs.count == 1
54
- inner
68
+ end
69
+
70
+
71
+ # @!group Display Instance Methods
72
+ # --------------------------------------------------------------------------
73
+
74
+ def string_format pre:, post:, method:, spaces: true
75
+ space = spaces ? ' ' : ''
76
+
77
+ inner = @pairs.map { |k, v|
78
+ key_part = if k.is_a? Symbol
79
+ "#{ k }:#{ space }"
55
80
  else
56
- '(' + inner + ')'
81
+ "#{ k.inspect }#{ space }=>#{ space }"
57
82
  end
58
- end
59
-
60
- def has_from_data?
61
- pairs.values.all? { |type| type.has_from_data? }
62
- end
63
-
64
-
65
- def custom_from_data data
66
- pairs.map { |key, type|
67
- [ key, type.from_data( data[key] ) ]
68
- }.to_h
69
- end
70
-
71
- end # class Shape
83
+
84
+ key_part + v.public_send( method )
85
+ }
86
+
87
+ pre + inner.join( ",#{ space }" ) + post
88
+ end
89
+
90
+
91
+ def default_symbolic
92
+ string_format pre: '{', post: '}', method: :symbolic
93
+ end
94
+
95
+
96
+ def explain
97
+ string_format pre: 'Shape<', post: '>', method: :explain
98
+ end
99
+
100
+ # @!endgroup Display Instance Methods # ************************************
101
+
102
+
103
+ def has_from_data?
104
+ pairs.values.all? { |type| type.has_from_data? }
105
+ end
72
106
 
73
107
 
74
- def_factory(
75
- :shape,
76
- ) do |pairs, **options|
77
- Shape.new pairs, **options
108
+ def custom_from_data data
109
+ pairs.map { |key, type|
110
+ [ key, type.from_data( data[key] ) ]
111
+ }.to_h
78
112
  end
79
113
 
80
- end # module NRSER::Types
114
+ end # class Shape
115
+
116
+
117
+ # @!group Shape Type Factories
118
+ # ----------------------------------------------------------------------------
119
+
120
+ #@!method self.Shape pairs, **options
121
+ # Create a {Shape} type that parameterizes `pairs` of object keys and {Type}
122
+ # values.
123
+ #
124
+ # Members of the type are values `v` for which for all keys `k` and
125
+ # paired value types `t_k` `v[k]` is a member of `t_k`:
126
+ #
127
+ # shape.pairs.all? { |k, t_k| t_k.test? v[k] }
128
+ #
129
+ # @param [Hash<Object, TYPE>] pairs
130
+ # See {Shape#initialize}.
131
+ #
132
+ # @param [Hash] options
133
+ # Passed to {Type#initialize}.
134
+ #
135
+ # @return [Shape]
136
+ #
137
+ def_type :Shape,
138
+ parameterize: true,
139
+ &->( pairs, **options ) do
140
+ Shape.new pairs, **options
141
+ end # .Shape
142
+
143
+ # @!endgroup Shape Type Factories # ******************************************
144
+
145
+
146
+ # /Namespace
147
+ # ========================================================================
148
+
149
+ end # module Types
150
+ end # module NRSER
151
+
@@ -1,72 +1,198 @@
1
+ # frozen_string_literal: true
2
+ # encoding: UTF-8
3
+
4
+
5
+ # Requirements
6
+ # ========================================================================
7
+
8
+ # Project / Package
9
+ # ------------------------------------------------------------------------
10
+
1
11
  require_relative './is'
2
12
  require_relative './is_a'
3
- require_relative './attrs'
13
+ require_relative './attributes'
4
14
  require_relative './not'
5
15
 
6
16
 
7
- module NRSER::Types
8
-
9
- # @!group Type Factory Functions
17
+ # Namespace
18
+ # ========================================================================
19
+
20
+ module NRSER
21
+ module Types
22
+
23
+
24
+ # Definitions
25
+ # ========================================================================
10
26
 
11
- def_factory(
12
- :String,
13
- aliases: [ :str, :string ],
14
- ) do |length: nil, encoding: nil, **options|
15
- if [length, encoding].all?( &:nil? )
16
- IsA.new ::String, from_s: ->(s) { s }, **options
17
-
27
+ # @!group String Type Factories
28
+ # ----------------------------------------------------------------------------
29
+
30
+ #@!method self.String length: nil, encoding: nil, **options
31
+ # Get a {Type} whose members {.IsA} {::String}, along with some other optional
32
+ # common attribute checks ({::String#length} and {::String#encoding}).
33
+ #
34
+ # If `encoding:` is specified and no `from_s:` is provided, will add a
35
+ # {Type#form_s} that attempts to transcode strings that are not already in the
36
+ # target encoding (via a simple `String#encode( encoding )`).
37
+ #
38
+ # If you for some reason don't want {Type#from_s} to try to transcode, just
39
+ # provide a `from_s:` {Proc} that doesn't do it - `->( s ) { s }` to just
40
+ # use whatever tha cat drags in.
41
+ #
42
+ # If `from_s` is otherwise not provided, adds the obvious identity function.
43
+ #
44
+ # @param [nil | Integer | {min: Integer?, max: Integer?, length: Integer?}]
45
+ # length
46
+ # Optionally admit only strings of a specified length. This does not affect
47
+ # any default `from_s` - loaded strings must already be the specific length.
48
+ #
49
+ # @param [String] encoding
50
+ # Optional {::String#encoding} check. See notes above regarding default
51
+ # `from_s` that may be added.
52
+ #
53
+ # @param [Hash] options
54
+ # Passed to {Type#initialize}.
55
+ #
56
+ # @return [Type]
57
+ #
58
+ def_type :String,
59
+ aliases: [ :str ],
60
+ &->( length: nil, encoding: nil, **options ) do
61
+
62
+ if [ length, encoding ].all?( &:nil? )
63
+ # Give 'er the obvious `#from_s` if she don't already have one
64
+ options[:from_s] ||= ->( s ) { s }
65
+
66
+ IsA.new ::String, **options
67
+
68
+ else
69
+ types = [ IsA.new( ::String ) ]
70
+ types << self.Length( length ) if length
71
+
72
+ if encoding
73
+ # If we didn't get a `from_s`, provide one that will try to transcode to
74
+ # `encoding` (unless it's already there)
75
+ options[:from_s] ||= ->( string ) {
76
+ if string.encoding == encoding
77
+ string
78
+ else
79
+ string.encode encoding
80
+ end
81
+ }
82
+
83
+ types << self.Attributes( encoding: encoding )
84
+
18
85
  else
19
- types = [str]
20
- types << self.length( length ) if length
21
- types << attrs( encoding: encoding ) if encoding
22
-
23
- intersection *types, **options
86
+ # We don't need to handle encoding, so set the obvious `#from_s` if
87
+ # one was not provided
88
+ options[:from_s] ||= ->( s ) { s }
89
+
24
90
  end
25
- end # String
26
-
27
-
28
- # Get a {Type} only satisfied by empty strings.
29
- #
30
- # @param [String] name: (default 'EmptyString')
31
- #
32
- def_factory(
33
- :EmptyString,
34
- aliases: [ :empty_str, :empty_string ],
35
- ) do |name: 'EmptyString', **options|
36
- str length: 0, name: name, **options
37
- end
38
-
39
-
40
- def_factory(
41
- :NonEmptyString,
42
- aliases: [ :non_empty_str, :non_empty_string ],
43
- ) do |name: 'NonEmptyString', **options|
44
- str length: {min: 1}, name: name, **options
45
- end
46
-
47
-
48
- def_factory(
49
- :Character,
50
- aliases: [ :char, :character ],
51
- ) do |name: 'Character', **options|
52
- str length: 1, name: name, **options
91
+
92
+ self.Intersection *types, **options
53
93
  end
54
-
55
-
56
- # A type satisfied by UTF-8 encoded strings.
57
- #
58
- # @param [String] name: (default 'UTF8String')
59
- #
60
- def_factory :uft_8, aliases: [:utf8] do |name: 'UTF8String', **options|
61
- str encoding: Encoding::UTF_8, name: name, **options
62
- end
63
-
64
-
65
- def_factory(
66
- :utf_8_char,
67
- aliases: [:utf8_char]
68
- ) do |name: 'UTF8Character', **options|
69
- str length: 1, encoding: Encoding::UTF_8, name: name, **options
70
- end
71
-
72
- end # NRSER::Types
94
+
95
+ end # .String
96
+
97
+
98
+ #@!method self.EmptyString encoding: nil, **options
99
+ # Get a {Type} only satisfied by empty strings.
100
+ #
101
+ # @param encoding (see .String)
102
+ #
103
+ # @param [Hash] options
104
+ # Passed to {Type#initialize}.
105
+ #
106
+ # @return [Type]
107
+ #
108
+ def_type :EmptyString,
109
+ aliases: [ :empty_str ],
110
+ &->( encoding: nil, **options ) do
111
+ self.String **options, length: 0, encoding: encoding
112
+ end # .EmptyString
113
+
114
+
115
+ #@!method self.NonEmptyString encoding: nil, **options
116
+ # {.String} of length `1` or more.
117
+ #
118
+ # @param encoding (see .String)
119
+ #
120
+ # @param [Hash] options
121
+ # Passed to {Type#initialize}.
122
+ #
123
+ # @return [Type]
124
+ #
125
+ def_type :NonEmptyString,
126
+ aliases: [ :non_empty_str ],
127
+ &->( encoding: nil, **options ) do
128
+ self.String **options, length: {min: 1}, encoding: encoding
129
+ end # .NonEmptyString
130
+
131
+
132
+ #@!method self.Character encoding: nil, **options
133
+ # {.String} of length `1` (Ruby lacks a character class).
134
+ #
135
+ # @param encoding (see .String)
136
+ #
137
+ # @param [Hash] options
138
+ # Passed to {Type#initialize}.
139
+ #
140
+ # @return [Type]
141
+ #
142
+ def_type :Character,
143
+ aliases: [ :char ],
144
+ &->( encoding: nil, **options ) do
145
+ self.String **options, length: 1, encoding: encoding
146
+ end # .Character
147
+
148
+
149
+ #@!method self.UTF8String length: nil, **options
150
+ # A type satisfied by UTF-8 encoded {.String}.
151
+ #
152
+ # @param length (see .String)
153
+ #
154
+ # @param [Hash] options
155
+ # Passed to {Type#initialize}.
156
+ #
157
+ # @return [Type]
158
+ #
159
+ def_type :UTF8String,
160
+ # NOTE "UTF8String".underscore -> "utf8_string"
161
+ aliases: [ :utf_8_string,
162
+ :utf8,
163
+ :utf_8,
164
+ :utf8_str,
165
+ :utf_8_str ],
166
+ &->( length: nil, **options ) do
167
+ self.String **options, length: length, encoding: Encoding::UTF_8
168
+ end # .UTF8String
169
+
170
+
171
+ #@!method self.UTF8Character **options
172
+ # A type satisfied by UTF-8 encoded {.Character}.
173
+ #
174
+ # @param encoding (see .String)
175
+ #
176
+ # @param [Hash] options
177
+ # Passed to {Type#initialize}.
178
+ #
179
+ # @return [Type]
180
+ #
181
+ def_type :UTF8Character,
182
+ # NOTE "UTF8Character".underscore -> "utf8_character"
183
+ aliases: [ :utf_8_character,
184
+ :utf8_char,
185
+ :utf_8_char ],
186
+ &->( **options ) do
187
+ self.Character **options, encoding: Encoding::UTF_8
188
+ end # .UTF8Character
189
+
190
+
191
+ # @!endgroup String Type Factories # *****************************************
192
+
193
+
194
+ # /Namespace
195
+ # ========================================================================
196
+
197
+ end # module Types
198
+ end # module NRSER