nrser 0.3.9 → 0.3.10

Sign up to get free protection for your applications and to get access to all the features.
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