attribute_struct 0.4.2 → 0.5.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 +5 -5
- data/CHANGELOG.md +6 -0
- data/CONTRIBUTING.md +10 -14
- data/LICENSE +2 -2
- data/attribute_struct.gemspec +15 -13
- data/lib/attribute_struct/attribute_hash.rb +7 -9
- data/lib/attribute_struct/attribute_struct.rb +118 -87
- data/lib/attribute_struct/augmented.rb +0 -4
- data/lib/attribute_struct/irb_compat.rb +10 -9
- data/lib/attribute_struct/monkey_camels.rb +28 -20
- data/lib/attribute_struct/version.rb +1 -1
- data/lib/attribute_struct.rb +3 -7
- metadata +31 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a88c87931988bfa2b2e576583dbfb8ee6a8b1c5091cb1c62b58f39dddf7f89ec
|
4
|
+
data.tar.gz: 743c6adaaa2992229bcc42e5daf0cebd9a59c91a12f3f83c06a7a4eba672e02f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8df0dcb1c017726e1a2a3b698979fb1e257df3b18e02a7812a27ba7c7e7cfb50fe1fdbdc20625497d4b6eab339ef793d086c70504cc4ec3b7051cac9b75cdb1
|
7
|
+
data.tar.gz: fa93e5e6850bd7d3cb516b6d6e6ca770a6660b561a13c5abf0da15df5b86a3c81ca7c0644c84fcc07cea100225b80c686002a00d5051057da9981633fb5c4c53
|
data/CHANGELOG.md
CHANGED
data/CONTRIBUTING.md
CHANGED
@@ -1,22 +1,18 @@
|
|
1
1
|
# Contributing
|
2
2
|
|
3
|
-
##
|
3
|
+
## Fixes
|
4
4
|
|
5
|
-
|
5
|
+
Have a fix to some bug you want to submit? Well you're
|
6
|
+
awesome. Please just include a description of the bug
|
7
|
+
(or link to originating issue) and test coverage on the
|
8
|
+
modifications.
|
6
9
|
|
7
|
-
|
10
|
+
## New Features
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
## Pull requests
|
14
|
-
|
15
|
-
* https://github.com/chrisroberts/attribute_struct/pulls
|
16
|
-
|
17
|
-
Please base all pull requests off the `develop` branch. Merges to
|
18
|
-
`master` only occur through the `develop` branch. Pull requests
|
19
|
-
based on `master` will likely be cherry picked.
|
12
|
+
Have a new feature you want to add? Well you're awesome
|
13
|
+
too! It may be a good idea to submit an issue first to
|
14
|
+
describe the desired feature and get any feedback. Please
|
15
|
+
be sure to include tests.
|
20
16
|
|
21
17
|
## Issues
|
22
18
|
|
data/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright
|
1
|
+
Copyright 2022 Chris Roberts
|
2
2
|
|
3
3
|
Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
you may not use this file except in compliance with the License.
|
@@ -10,4 +10,4 @@
|
|
10
10
|
distributed under the License is distributed on an "AS IS" BASIS,
|
11
11
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
12
|
See the License for the specific language governing permissions and
|
13
|
-
limitations under the License.
|
13
|
+
limitations under the License.
|
data/attribute_struct.gemspec
CHANGED
@@ -1,16 +1,18 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__)) +
|
2
|
-
require
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__)) + "/lib/"
|
2
|
+
require "attribute_struct/version"
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.name =
|
4
|
+
s.name = "attribute_struct"
|
5
5
|
s.version = AttributeStruct::VERSION.version
|
6
|
-
s.summary =
|
7
|
-
s.author =
|
8
|
-
s.license =
|
9
|
-
s.email =
|
10
|
-
s.homepage =
|
11
|
-
s.description =
|
12
|
-
s.require_path =
|
13
|
-
s.add_runtime_dependency
|
14
|
-
s.add_development_dependency
|
15
|
-
s.
|
6
|
+
s.summary = "Attribute structures"
|
7
|
+
s.author = "Chris Roberts"
|
8
|
+
s.license = "Apache 2.0"
|
9
|
+
s.email = "chrisroberts.code@gmail.com"
|
10
|
+
s.homepage = "http://github.com/chrisroberts/attribute_struct"
|
11
|
+
s.description = "Attribute structures"
|
12
|
+
s.require_path = "lib"
|
13
|
+
s.add_runtime_dependency "bogo", ">= 0.1.31", "< 0.3.0"
|
14
|
+
s.add_development_dependency "rspec", "~> 3.5"
|
15
|
+
s.add_development_dependency "rake", "~> 13"
|
16
|
+
s.add_development_dependency "minitest"
|
17
|
+
s.files = Dir["lib/**/*"] + %w(attribute_struct.gemspec README.md CHANGELOG.md CONTRIBUTING.md LICENSE)
|
16
18
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'attribute_struct'
|
2
|
-
|
3
1
|
class AttributeStruct
|
4
2
|
|
5
3
|
# Copyright (c) 2009 Dan Kubb
|
@@ -75,7 +73,7 @@ class AttributeStruct
|
|
75
73
|
def initialize_copy(orig)
|
76
74
|
super
|
77
75
|
# Handle nested values
|
78
|
-
each do |k,v|
|
76
|
+
each do |k, v|
|
79
77
|
if v.kind_of?(Mash) || v.is_a?(Array)
|
80
78
|
self[k] = v.dup
|
81
79
|
end
|
@@ -150,7 +148,7 @@ class AttributeStruct
|
|
150
148
|
#
|
151
149
|
# @return [Array] The values at each of the provided keys
|
152
150
|
def values_at(*indices)
|
153
|
-
indices.collect {|key| self[convert_key(key)]}
|
151
|
+
indices.collect { |key| self[convert_key(key)] }
|
154
152
|
end
|
155
153
|
|
156
154
|
# @param hash<Hash> The hash to merge with the mash.
|
@@ -174,7 +172,7 @@ class AttributeStruct
|
|
174
172
|
# { :one => 1, :two => 2, :three => 3 }.except(:one)
|
175
173
|
# #=> { "two" => 2, "three" => 3 }
|
176
174
|
def except(*keys)
|
177
|
-
super(*keys.map {|k| convert_key(k)})
|
175
|
+
super(*keys.map { |k| convert_key(k) })
|
178
176
|
end
|
179
177
|
|
180
178
|
# Used to provide the same interface as Hash.
|
@@ -206,6 +204,7 @@ class AttributeStruct
|
|
206
204
|
end
|
207
205
|
|
208
206
|
protected
|
207
|
+
|
209
208
|
# @param key<Object> The key to convert.
|
210
209
|
#
|
211
210
|
# @param [Object]
|
@@ -242,12 +241,12 @@ class AttributeStruct
|
|
242
241
|
#
|
243
242
|
# @return [AttributeStruct::Mash] merged hash
|
244
243
|
def deep_merge(hash)
|
245
|
-
unless(hash.is_a?(Hash))
|
244
|
+
unless (hash.is_a?(Hash))
|
246
245
|
raise ArgumentError.new "Expecting `Hash` type. Received: `#{hash.class}`"
|
247
246
|
end
|
248
247
|
new_self = self.dup
|
249
|
-
hash.each do |k,v|
|
250
|
-
if(new_self[k].is_a?(Hash) && v.is_a?(Hash))
|
248
|
+
hash.each do |k, v|
|
249
|
+
if (new_self[k].is_a?(Hash) && v.is_a?(Hash))
|
251
250
|
new_self[k] = new_self[k].deep_merge(v)
|
252
251
|
else
|
253
252
|
new_self[k] = v
|
@@ -263,7 +262,6 @@ class AttributeStruct
|
|
263
262
|
self.replace(self.deep_merge(hash))
|
264
263
|
self
|
265
264
|
end
|
266
|
-
|
267
265
|
end
|
268
266
|
|
269
267
|
AttributeHash = Mash
|
@@ -1,10 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require "attribute_struct/attribute_hash"
|
2
|
+
require "attribute_struct/augmented"
|
3
|
+
require "attribute_struct/monkey_camels"
|
2
4
|
|
3
5
|
class AttributeStruct < BasicObject
|
4
|
-
|
5
|
-
autoload :Augmented, 'attribute_struct/augmented'
|
6
|
-
autoload :Mash, 'attribute_struct/attribute_hash'
|
7
|
-
|
8
6
|
class << self
|
9
7
|
|
10
8
|
# @return [Hash] valid styles and mapped value
|
@@ -14,7 +12,7 @@ class AttributeStruct < BasicObject
|
|
14
12
|
:no_leading => :no_leading,
|
15
13
|
:dromedary => :leading,
|
16
14
|
:leading_hump => :leading,
|
17
|
-
:leading => :leading
|
15
|
+
:leading => :leading,
|
18
16
|
}
|
19
17
|
|
20
18
|
# @return [Truthy, Falsey] global flag for camel keys
|
@@ -46,17 +44,19 @@ class AttributeStruct < BasicObject
|
|
46
44
|
# @return [Symbol]
|
47
45
|
# @raises [ArgumentError]
|
48
46
|
def validate_camel_style(style)
|
49
|
-
if(VALID_CAMEL_STYLES.has_key?(style))
|
47
|
+
if (VALID_CAMEL_STYLES.has_key?(style))
|
50
48
|
VALID_CAMEL_STYLES[style]
|
51
49
|
else
|
52
|
-
|
50
|
+
valid_types = VALID_CAMEL_STYLES.keys(&:inspect).join(", ")
|
51
|
+
raise ArgumentError.new "Unsupported camel style provided " \
|
52
|
+
"`#{style.inspect}`! (Allowed: #{valid_types})"
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
56
|
# Loads helpers for camel casing
|
57
57
|
def load_the_camels
|
58
|
-
unless(@camels_loaded)
|
59
|
-
require
|
58
|
+
unless defined?(@camels_loaded)
|
59
|
+
require "attribute_struct/monkey_camels"
|
60
60
|
@camels_loaded = true
|
61
61
|
end
|
62
62
|
end
|
@@ -68,7 +68,7 @@ class AttributeStruct < BasicObject
|
|
68
68
|
|
69
69
|
# Create AttributeStruct instance and dump the resulting hash
|
70
70
|
def build(&block)
|
71
|
-
raise ArgumentError.new
|
71
|
+
raise ArgumentError.new "Block required for build!" unless block
|
72
72
|
new(&block)._dump
|
73
73
|
end
|
74
74
|
|
@@ -80,7 +80,6 @@ class AttributeStruct < BasicObject
|
|
80
80
|
self.send(:include, IrbCompat)
|
81
81
|
true
|
82
82
|
end
|
83
|
-
|
84
83
|
end
|
85
84
|
|
86
85
|
# value used to identify unset value
|
@@ -103,15 +102,18 @@ class AttributeStruct < BasicObject
|
|
103
102
|
#
|
104
103
|
# @param init_hash [Hash] hash to initialize struct
|
105
104
|
# @yield block to execute within struct context
|
106
|
-
def initialize(init_hash=nil, &block)
|
105
|
+
def initialize(init_hash = nil, &block)
|
107
106
|
@_camel_keys = _klass.camel_keys
|
107
|
+
@_camel_keys_set = nil
|
108
|
+
@_parent = nil
|
108
109
|
@_arg_state = __hashish.new
|
110
|
+
@_kernelified = false
|
109
111
|
@_objectified = false
|
110
112
|
@table = __hashish.new
|
111
|
-
if(init_hash)
|
113
|
+
if (init_hash)
|
112
114
|
_load(init_hash)
|
113
115
|
end
|
114
|
-
if(block)
|
116
|
+
if (block)
|
115
117
|
self.instance_exec(&block)
|
116
118
|
end
|
117
119
|
end
|
@@ -123,15 +125,17 @@ class AttributeStruct < BasicObject
|
|
123
125
|
def _build(&block)
|
124
126
|
self.instance_exec(&block)
|
125
127
|
end
|
128
|
+
|
126
129
|
alias_method :build!, :_build
|
127
130
|
|
128
131
|
# Set state into current context
|
129
132
|
#
|
130
133
|
# @param args [Hashish] hashish type holding data for context
|
131
134
|
# @return [Hashish]
|
132
|
-
def _set_state(args={})
|
135
|
+
def _set_state(args = {})
|
133
136
|
_arg_state.merge!(args)
|
134
137
|
end
|
138
|
+
|
135
139
|
alias_method :set_state!, :_set_state
|
136
140
|
|
137
141
|
# Value of requested state
|
@@ -139,15 +143,16 @@ class AttributeStruct < BasicObject
|
|
139
143
|
# @param key [Symbol, String]
|
140
144
|
# @param traverse [TrueClass, FalseClass] traverse towards root for matching key
|
141
145
|
# @return [Object, NilClass]
|
142
|
-
def _state(key, traverse=true)
|
143
|
-
if(_arg_state.has_key?(key))
|
146
|
+
def _state(key, traverse = true)
|
147
|
+
if (_arg_state.has_key?(key))
|
144
148
|
_arg_state[key]
|
145
149
|
else
|
146
|
-
if(traverse && _parent)
|
150
|
+
if (traverse && _parent)
|
147
151
|
_parent._state(key)
|
148
152
|
end
|
149
153
|
end
|
150
154
|
end
|
155
|
+
|
151
156
|
alias_method :state!, :_state
|
152
157
|
|
153
158
|
# Enable/disable camel keys
|
@@ -171,9 +176,10 @@ class AttributeStruct < BasicObject
|
|
171
176
|
#
|
172
177
|
# @param enable [TrueClass, FalseClass]
|
173
178
|
# @return [TrueClass, FalseClass]
|
174
|
-
def _objectify(enable=true)
|
179
|
+
def _objectify(enable = true)
|
175
180
|
@_objectified = !!enable
|
176
181
|
end
|
182
|
+
|
177
183
|
alias_method :objectify!, :_objectify
|
178
184
|
|
179
185
|
# @return [TrueClass, FalseClass]
|
@@ -196,13 +202,14 @@ class AttributeStruct < BasicObject
|
|
196
202
|
# @param val [Object]
|
197
203
|
# @yield block to execute within context
|
198
204
|
# @return [Object]
|
199
|
-
def _set(key, val=UNSET_VALUE, &block)
|
200
|
-
if(val != UNSET_VALUE)
|
205
|
+
def _set(key, val = UNSET_VALUE, &block)
|
206
|
+
if (val != UNSET_VALUE)
|
201
207
|
self.method_missing(key, val, &block)
|
202
208
|
else
|
203
209
|
self.method_missing(key, &block)
|
204
210
|
end
|
205
211
|
end
|
212
|
+
|
206
213
|
alias_method :set!, :_set
|
207
214
|
|
208
215
|
# Provides struct DSL behavior
|
@@ -213,66 +220,66 @@ class AttributeStruct < BasicObject
|
|
213
220
|
# @return [Object] existing value or newly set value
|
214
221
|
# @note Dragons and unicorns all over in here
|
215
222
|
def method_missing(_sym, *_args, &_block)
|
216
|
-
if(objectified? && _args.empty? && _block.nil?)
|
223
|
+
if (objectified? && _args.empty? && _block.nil?)
|
217
224
|
_o_lookup = _objectified_constant_lookup(_sym)
|
218
225
|
return _o_lookup if _o_lookup
|
219
226
|
end
|
220
|
-
if(_sym.is_a?(::String) || _sym.is_a?(::Symbol))
|
221
|
-
if((_s = _sym.to_s).end_with?(
|
227
|
+
if (_sym.is_a?(::String) || _sym.is_a?(::Symbol))
|
228
|
+
if ((_s = _sym.to_s).end_with?("="))
|
222
229
|
_s.slice!(-1, _s.length)
|
223
230
|
_sym = _s
|
224
231
|
end
|
225
232
|
_sym = _process_key(_sym)
|
226
233
|
end
|
227
|
-
if(!_args.empty? || _block)
|
228
|
-
if(_args.empty? && _block)
|
234
|
+
if (!_args.empty? || _block)
|
235
|
+
if (_args.empty? && _block)
|
229
236
|
_base = @table.fetch(_sym, UNSET_VALUE)
|
230
|
-
if(_state(:value_collapse) && !_base.is_a?(self.class!))
|
237
|
+
if (_state(:value_collapse) && !_base.is_a?(self.class!))
|
231
238
|
_orig = _base
|
232
239
|
_base = _klass_new
|
233
240
|
else
|
234
|
-
unless(_base.is_a?(self.class!))
|
241
|
+
unless (_base.is_a?(self.class!))
|
235
242
|
_base = _klass_new
|
236
243
|
end
|
237
244
|
end
|
238
245
|
@table[_sym] = _base
|
239
|
-
if(_block.arity == 0)
|
246
|
+
if (_block.arity == 0)
|
240
247
|
_base.instance_exec(&_block)
|
241
248
|
else
|
242
249
|
_base.instance_exec(_base, &_block)
|
243
250
|
end
|
244
|
-
if(_orig.is_a?(::NilClass))
|
251
|
+
if (_orig.is_a?(::NilClass))
|
245
252
|
@table[_sym] = _base
|
246
253
|
else
|
247
|
-
if(_orig == UNSET_VALUE)
|
254
|
+
if (_orig == UNSET_VALUE)
|
248
255
|
@table[_sym] = _base
|
249
256
|
else
|
250
|
-
unless(_orig.is_a?(CollapseArray))
|
257
|
+
unless (_orig.is_a?(CollapseArray))
|
251
258
|
_orig = CollapseArray.new.push(_orig)
|
252
259
|
end
|
253
260
|
_orig << _base
|
254
261
|
@table[_sym] = _orig
|
255
262
|
end
|
256
263
|
end
|
257
|
-
elsif(!_args.empty? && _block)
|
264
|
+
elsif (!_args.empty? && _block)
|
258
265
|
_result = _leaf = _base = @table.fetch(_sym, _klass_new)
|
259
266
|
@table[_sym] = _result
|
260
267
|
|
261
268
|
_args.flatten.each do |_arg|
|
262
269
|
_leaf = _base[_arg]
|
263
|
-
unless(_leaf.is_a?(_klass))
|
270
|
+
unless (_leaf.is_a?(_klass))
|
264
271
|
_leaf = _klass_new
|
265
272
|
_base._set(_arg, _leaf)
|
266
273
|
_base = _leaf
|
267
274
|
end
|
268
275
|
end
|
269
|
-
if(!_leaf.nil? && _state(:value_collapse))
|
276
|
+
if (!_leaf.nil? && _state(:value_collapse))
|
270
277
|
_orig = _leaf
|
271
278
|
_leaf = _orig.parent._klass_new
|
272
279
|
end
|
273
280
|
_block.arity == 0 ? _leaf._build(&_block) : _leaf._build(_leaf, &_block)
|
274
|
-
if(_orig)
|
275
|
-
unless(_orig.is_a?(CollapseArray))
|
281
|
+
if (_orig)
|
282
|
+
unless (_orig.is_a?(CollapseArray))
|
276
283
|
_orig = CollapseArray.new.push(_orig)
|
277
284
|
end
|
278
285
|
_orig << _leaf
|
@@ -280,19 +287,19 @@ class AttributeStruct < BasicObject
|
|
280
287
|
_orig = _leaf
|
281
288
|
end
|
282
289
|
else
|
283
|
-
if(_args.size > 1 && _args.all?{|_i| _i.is_a?(::String) || _i.is_a?(::Symbol)} && !_state(:value_collapse))
|
290
|
+
if (_args.size > 1 && _args.all? { |_i| _i.is_a?(::String) || _i.is_a?(::Symbol) } && !_state(:value_collapse))
|
284
291
|
@table[_sym] = _klass_new unless @table[_sym].is_a?(_klass)
|
285
292
|
_endpoint = _args.inject(@table[_sym]) do |_memo, _k|
|
286
|
-
unless(_memo[_k].is_a?(_klass))
|
293
|
+
unless (_memo[_k].is_a?(_klass))
|
287
294
|
_memo._set(_k, _klass_new)
|
288
295
|
end
|
289
296
|
_memo[_k]
|
290
297
|
end
|
291
298
|
return _endpoint # custom break out
|
292
299
|
else
|
293
|
-
if(_args.size > 1)
|
300
|
+
if (_args.size > 1)
|
294
301
|
_val = _args.map do |_v|
|
295
|
-
if(_v.is_a?(::Hash) && _state(:hash_load_struct))
|
302
|
+
if (_v.is_a?(::Hash) && _state(:hash_load_struct))
|
296
303
|
_val = _klass_new
|
297
304
|
_val._load(_v)
|
298
305
|
else
|
@@ -300,15 +307,15 @@ class AttributeStruct < BasicObject
|
|
300
307
|
end
|
301
308
|
end
|
302
309
|
else
|
303
|
-
if(_args.first.is_a?(::Hash) && _state(:hash_load_struct))
|
310
|
+
if (_args.first.is_a?(::Hash) && _state(:hash_load_struct))
|
304
311
|
_val = _klass_new
|
305
312
|
_val._load(_args.first)
|
306
313
|
else
|
307
314
|
_val = _args.first
|
308
315
|
end
|
309
316
|
end
|
310
|
-
if(_state(:value_collapse) && !(_leaf = @table[_sym]).nil?)
|
311
|
-
unless(_leaf.is_a?(CollapseArray))
|
317
|
+
if (_state(:value_collapse) && !(_leaf = @table[_sym]).nil?)
|
318
|
+
unless (_leaf.is_a?(CollapseArray))
|
312
319
|
_leaf = CollapseArray.new.push(_leaf)
|
313
320
|
end
|
314
321
|
_leaf << _val
|
@@ -340,18 +347,31 @@ class AttributeStruct < BasicObject
|
|
340
347
|
def is_a?(klass)
|
341
348
|
(_klass.ancestors + [::AttributeStruct]).include?(klass)
|
342
349
|
end
|
350
|
+
|
343
351
|
alias_method :kind_of?, :is_a?
|
344
352
|
|
353
|
+
# Check if key exists within struct
|
354
|
+
#
|
355
|
+
# @param key [String, Symbol]
|
356
|
+
# @return [TrueClass, FalseClass]
|
357
|
+
def key?(key)
|
358
|
+
self._keys.include?(_process_key(key))
|
359
|
+
end
|
360
|
+
|
361
|
+
alias_method :has_key?, :key?
|
362
|
+
|
345
363
|
# @return [Array<String,Symbol>] keys within struct
|
346
364
|
def _keys
|
347
365
|
_data.keys
|
348
366
|
end
|
367
|
+
|
349
368
|
alias_method :keys!, :_keys
|
350
369
|
|
351
370
|
# @return [AttributeStruct::AttributeHash, Mash] underlying struct data
|
352
371
|
def _data
|
353
372
|
@table
|
354
373
|
end
|
374
|
+
|
355
375
|
alias_method :data!, :_data
|
356
376
|
|
357
377
|
# Delete entry from struct
|
@@ -361,6 +381,7 @@ class AttributeStruct < BasicObject
|
|
361
381
|
def _delete(key)
|
362
382
|
_data.delete(_process_key(key))
|
363
383
|
end
|
384
|
+
|
364
385
|
alias_method :delete!, :_delete
|
365
386
|
|
366
387
|
# Process and unpack items for dumping within deeply nested
|
@@ -369,8 +390,8 @@ class AttributeStruct < BasicObject
|
|
369
390
|
# @param item [Object]
|
370
391
|
# @return [Object]
|
371
392
|
def _dump_unpacker(item)
|
372
|
-
if(item.is_a?(::Enumerable))
|
373
|
-
if(item.respond_to?(:keys))
|
393
|
+
if (item.is_a?(::Enumerable))
|
394
|
+
if (item.respond_to?(:keys))
|
374
395
|
item.class[
|
375
396
|
*item.map do |entry|
|
376
397
|
_dump_unpacker(entry)
|
@@ -383,7 +404,7 @@ class AttributeStruct < BasicObject
|
|
383
404
|
end
|
384
405
|
]
|
385
406
|
end
|
386
|
-
elsif(item.is_a?(::AttributeStruct))
|
407
|
+
elsif (item.is_a?(::AttributeStruct))
|
387
408
|
item.nil? ? UNSET_VALUE : item._dump
|
388
409
|
else
|
389
410
|
item
|
@@ -399,6 +420,7 @@ class AttributeStruct < BasicObject
|
|
399
420
|
end.compact
|
400
421
|
__hashish[*processed.flatten(1)]
|
401
422
|
end
|
423
|
+
|
402
424
|
alias_method :dump!, :_dump
|
403
425
|
|
404
426
|
# Clear current struct data and replace
|
@@ -407,22 +429,22 @@ class AttributeStruct < BasicObject
|
|
407
429
|
# @return [self]
|
408
430
|
def _load(hashish)
|
409
431
|
@table.clear
|
410
|
-
if(_root._camel_keys_action == :auto_discovery)
|
411
|
-
starts = hashish.keys.map{|k|k[0,1]}
|
412
|
-
unless(starts.detect{|k| k =~ /[A-Z]/})
|
432
|
+
if (_root._camel_keys_action == :auto_discovery)
|
433
|
+
starts = hashish.keys.map { |k| k[0, 1] }
|
434
|
+
unless (starts.detect { |k| k =~ /[A-Z]/ })
|
413
435
|
_camel_keys_set(:auto_disable)
|
414
436
|
else
|
415
437
|
_camel_keys_set(:auto_enable) unless _parent.nil?
|
416
438
|
end
|
417
439
|
end
|
418
440
|
hashish.each do |key, value|
|
419
|
-
if(value.is_a?(::Enumerable))
|
441
|
+
if (value.is_a?(::Enumerable))
|
420
442
|
flat = value.map do |v|
|
421
443
|
v.is_a?(::Hash) ? _klass_new(v) : v
|
422
444
|
end
|
423
445
|
value = value.is_a?(::Hash) ? __hashish[*flat.flatten(1)] : flat
|
424
446
|
end
|
425
|
-
if(value.is_a?(::Hash))
|
447
|
+
if (value.is_a?(::Hash))
|
426
448
|
self._set(key)._load(value)
|
427
449
|
else
|
428
450
|
self._set(key, value)
|
@@ -430,6 +452,7 @@ class AttributeStruct < BasicObject
|
|
430
452
|
end
|
431
453
|
self
|
432
454
|
end
|
455
|
+
|
433
456
|
alias_method :load!, :_load
|
434
457
|
|
435
458
|
# Perform deep merge
|
@@ -475,14 +498,14 @@ class AttributeStruct < BasicObject
|
|
475
498
|
#
|
476
499
|
# @param thing [Object] struct to copy. defaults to self
|
477
500
|
# @return [Object] new instance
|
478
|
-
def _deep_copy(thing=nil)
|
501
|
+
def _deep_copy(thing = nil)
|
479
502
|
thing ||= _dump
|
480
|
-
if(thing.is_a?(::Enumerable))
|
481
|
-
val = thing.map{|v| v.is_a?(::Enumerable) ? _deep_copy(v) : _do_dup(v) }
|
503
|
+
if (thing.is_a?(::Enumerable))
|
504
|
+
val = thing.map { |v| v.is_a?(::Enumerable) ? _deep_copy(v) : _do_dup(v) }
|
482
505
|
else
|
483
506
|
val = _do_dup(thing)
|
484
507
|
end
|
485
|
-
if(thing.is_a?(::Hash))
|
508
|
+
if (thing.is_a?(::Hash))
|
486
509
|
val = __hashish[*val.flatten(1)]
|
487
510
|
end
|
488
511
|
val
|
@@ -494,9 +517,9 @@ class AttributeStruct < BasicObject
|
|
494
517
|
# @param args [Object] argument list (:force will force processing)
|
495
518
|
# @return [String, Symbol]
|
496
519
|
def _process_key(key, *args)
|
497
|
-
if(key.is_a?(::String) || key.is_a?(::Symbol))
|
498
|
-
key =
|
499
|
-
if(_camel_keys && _camel_keys_action && !key._hump_format_requested?)
|
520
|
+
if (key.is_a?(::String) || key.is_a?(::Symbol))
|
521
|
+
key = CamelString.new(key.to_s)
|
522
|
+
if (_camel_keys && _camel_keys_action && !key._hump_format_requested?)
|
500
523
|
case _camel_keys_action
|
501
524
|
when :auto_disable
|
502
525
|
key._no_hump
|
@@ -504,10 +527,10 @@ class AttributeStruct < BasicObject
|
|
504
527
|
key._hump
|
505
528
|
end
|
506
529
|
end
|
507
|
-
if(_camel_keys && (key._camel? || args.include?(:force)))
|
530
|
+
if (_camel_keys && (key._camel? || args.include?(:force)))
|
508
531
|
camel_args = [key]
|
509
|
-
if(key._hump_style || _camel_style == :no_leading)
|
510
|
-
unless(key._hump_style == :leading_hump)
|
532
|
+
if (key._hump_style || _camel_style == :no_leading)
|
533
|
+
unless (key._hump_style == :leading_hump)
|
511
534
|
camel_args << false
|
512
535
|
end
|
513
536
|
end
|
@@ -519,6 +542,7 @@ class AttributeStruct < BasicObject
|
|
519
542
|
key
|
520
543
|
end
|
521
544
|
end
|
545
|
+
|
522
546
|
alias_method :process_key!, :_process_key
|
523
547
|
|
524
548
|
# @return [Class] this class
|
@@ -530,6 +554,7 @@ class AttributeStruct < BasicObject
|
|
530
554
|
def klass!
|
531
555
|
_klass
|
532
556
|
end
|
557
|
+
|
533
558
|
alias_method :class!, :klass!
|
534
559
|
alias_method :class, :klass!
|
535
560
|
|
@@ -537,7 +562,7 @@ class AttributeStruct < BasicObject
|
|
537
562
|
# @note will set self as parent and propogate camelizing status
|
538
563
|
def _klass_new(*args, &block)
|
539
564
|
n = _klass.new(*args, &block)
|
540
|
-
unless(_camel_keys_action == :auto_discovery)
|
565
|
+
unless (_camel_keys_action == :auto_discovery)
|
541
566
|
n._camel_keys_set(_camel_keys_action)
|
542
567
|
end
|
543
568
|
n._camel_keys = _camel_keys
|
@@ -555,6 +580,7 @@ class AttributeStruct < BasicObject
|
|
555
580
|
def _camel_keys_set(v)
|
556
581
|
@_camel_keys_set = v
|
557
582
|
end
|
583
|
+
|
558
584
|
alias_method :camel_keys_set!, :_camel_keys_set
|
559
585
|
|
560
586
|
# @return [Symbol, NilClass] :auto_disable or :auto_enable
|
@@ -563,20 +589,22 @@ class AttributeStruct < BasicObject
|
|
563
589
|
end
|
564
590
|
|
565
591
|
# @return [AttributeStruct, NilClass] parent of this struct
|
566
|
-
def _parent(obj=nil)
|
592
|
+
def _parent(obj = nil)
|
567
593
|
@_parent = obj if obj
|
568
594
|
@_parent
|
569
595
|
end
|
596
|
+
|
570
597
|
alias_method :parent!, :_parent
|
571
598
|
|
572
599
|
# @return [AttributeStruct, NilClass] root of the struct or nil if self is root
|
573
600
|
def _root
|
574
601
|
r = self
|
575
|
-
until(r._parent == nil)
|
602
|
+
until (r._parent == nil)
|
576
603
|
r = r._parent
|
577
604
|
end
|
578
605
|
r
|
579
606
|
end
|
607
|
+
|
580
608
|
alias_method :root!, :_root
|
581
609
|
|
582
610
|
# Create an Array and evaluate discovered AttributeStructs
|
@@ -585,9 +613,9 @@ class AttributeStruct < BasicObject
|
|
585
613
|
# @return [Array]
|
586
614
|
def _array(*args)
|
587
615
|
args.map do |maybe_block|
|
588
|
-
if(maybe_block.is_a?(::Proc))
|
616
|
+
if (maybe_block.is_a?(::Proc))
|
589
617
|
klass = _klass_new
|
590
|
-
if(maybe_block.arity > 0)
|
618
|
+
if (maybe_block.arity > 0)
|
591
619
|
klass.instance_exec(klass, &maybe_block)
|
592
620
|
else
|
593
621
|
klass.instance_exec(&maybe_block)
|
@@ -598,6 +626,7 @@ class AttributeStruct < BasicObject
|
|
598
626
|
end
|
599
627
|
end
|
600
628
|
end
|
629
|
+
|
601
630
|
alias_method :array!, :_array
|
602
631
|
|
603
632
|
# Instance responds to method name
|
@@ -613,7 +642,7 @@ class AttributeStruct < BasicObject
|
|
613
642
|
# @param konst [Symbol, String]
|
614
643
|
# @return [Object, NilClass]
|
615
644
|
def _objectified_constant_lookup(konst)
|
616
|
-
if(konst.to_s[0].match(/[A-Z]/) && ::Object.const_defined?(konst))
|
645
|
+
if (konst.to_s[0].match(/[A-Z]/) && ::Object.const_defined?(konst))
|
617
646
|
::Object.const_get(konst)
|
618
647
|
end
|
619
648
|
end
|
@@ -622,7 +651,7 @@ class AttributeStruct < BasicObject
|
|
622
651
|
#
|
623
652
|
# @return [TrueClass]
|
624
653
|
def _kernelify
|
625
|
-
unless(kernelified?)
|
654
|
+
unless (kernelified?)
|
626
655
|
@_kernelified = true
|
627
656
|
(::Kernel.public_instance_methods + ::Kernel.private_instance_methods).each do |m_name|
|
628
657
|
self.instance_eval("def #{m_name}(*a, &b); ::Kernel.instance_method(:#{m_name}).bind(self).curry.call(*a, &b); end")
|
@@ -630,6 +659,7 @@ class AttributeStruct < BasicObject
|
|
630
659
|
end
|
631
660
|
true
|
632
661
|
end
|
662
|
+
|
633
663
|
alias_method :kernelify!, :_kernelify
|
634
664
|
|
635
665
|
# @return [TrueClass, FalseClass] Kernel methods have been injected
|
@@ -643,28 +673,29 @@ class AttributeStruct < BasicObject
|
|
643
673
|
end
|
644
674
|
|
645
675
|
# @return [AttributeStruct] clone of current instance
|
646
|
-
def _clone(_new_parent=nil)
|
676
|
+
def _clone(_new_parent = nil)
|
647
677
|
_cloned_inst = _klass_new
|
648
678
|
_cloned_inst._data.replace __hashish[
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
679
|
+
@table.map { |_key, _value|
|
680
|
+
if (_key.is_a?(::AttributeStruct))
|
681
|
+
_key = _key._clone
|
682
|
+
else
|
683
|
+
_key = _do_dup(_key)
|
684
|
+
end
|
685
|
+
if (_value.is_a?(::AttributeStruct))
|
686
|
+
_value = _value._clone
|
687
|
+
else
|
688
|
+
_value = _do_dup(_value)
|
689
|
+
end
|
690
|
+
[_key, _value]
|
691
|
+
}
|
692
|
+
]
|
663
693
|
_cloned_inst._parent(_new_parent) if _new_parent
|
664
694
|
_cloned_inst
|
665
695
|
end
|
696
|
+
|
666
697
|
alias_method :clone!, :_clone
|
667
698
|
end
|
668
699
|
|
669
|
-
require
|
670
|
-
require
|
700
|
+
require "attribute_struct/attribute_hash"
|
701
|
+
require "attribute_struct/version"
|
@@ -1,10 +1,7 @@
|
|
1
|
-
require 'attribute_struct'
|
2
|
-
|
3
1
|
class AttributeStruct
|
4
2
|
# AttributeStruct expanded class that include the Kernel module
|
5
3
|
# and automatically objectifies the instance
|
6
4
|
class Augmented < ::AttributeStruct
|
7
|
-
|
8
5
|
include ::Kernel
|
9
6
|
|
10
7
|
# Create a new Augmented AttributeStruct instance. Passes arguments
|
@@ -21,6 +18,5 @@ class AttributeStruct
|
|
21
18
|
def _klass
|
22
19
|
::AttributeStruct::Augmented
|
23
20
|
end
|
24
|
-
|
25
21
|
end
|
26
22
|
end
|
@@ -1,14 +1,15 @@
|
|
1
1
|
# Helper methods for IRB interactions
|
2
|
-
module
|
2
|
+
module AttributeStruct
|
3
|
+
module IrbCompat
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# @return [String] object inspection
|
6
|
+
def inspect
|
7
|
+
"<[#{self._klass}:#{@table.object_id}] - table: #{@table.inspect}>"
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
# @return [String] string of instance
|
11
|
+
def to_s
|
12
|
+
"<#{self._klass}:#{@table.object_id}>"
|
13
|
+
end
|
12
14
|
end
|
13
|
-
|
14
15
|
end
|
@@ -1,13 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
unless(defined?(MonkeyCamels))
|
4
|
-
|
1
|
+
class AttributeStruct
|
5
2
|
module MonkeyCamels
|
6
|
-
|
7
3
|
class << self
|
8
4
|
def included(klass)
|
9
5
|
klass.class_eval do
|
10
|
-
|
11
6
|
include Humps
|
12
7
|
|
13
8
|
alias_method :un_camel_to_s, :to_s
|
@@ -21,9 +16,9 @@ unless(defined?(MonkeyCamels))
|
|
21
16
|
# Create a camel copy based on settings
|
22
17
|
#
|
23
18
|
# @return [String]
|
24
|
-
def camel_initialize_copy(orig, hump=nil)
|
19
|
+
def camel_initialize_copy(orig, hump = nil)
|
25
20
|
new_val = un_camel_initialize_copy(orig)
|
26
|
-
if(hump.nil?)
|
21
|
+
if (hump.nil?)
|
27
22
|
orig._camel? ? new_val : new_val._no_hump
|
28
23
|
else
|
29
24
|
new_val._no_hump if hump == false
|
@@ -39,15 +34,22 @@ unless(defined?(MonkeyCamels))
|
|
39
34
|
end
|
40
35
|
|
41
36
|
module Humps
|
42
|
-
|
43
37
|
# @return [TrueClass, FalseClass] specific style requested
|
44
38
|
def _hump_format_requested?
|
45
|
-
@__not_camel
|
39
|
+
if defined?(@__not_camel)
|
40
|
+
@__not_camel != nil
|
41
|
+
else
|
42
|
+
false
|
43
|
+
end
|
46
44
|
end
|
47
45
|
|
48
46
|
# @return [TrueClass, FalseClass] camelized
|
49
47
|
def _camel?
|
50
|
-
|
48
|
+
if defined?(@__not_camel)
|
49
|
+
!@__not_camel
|
50
|
+
else
|
51
|
+
true
|
52
|
+
end
|
51
53
|
end
|
52
54
|
|
53
55
|
# @return [self] disable camelizing
|
@@ -55,6 +57,7 @@ unless(defined?(MonkeyCamels))
|
|
55
57
|
@__not_camel = true
|
56
58
|
self
|
57
59
|
end
|
60
|
+
|
58
61
|
alias_method :disable_camel!, :_no_hump
|
59
62
|
|
60
63
|
# @return [self] enable camelizing
|
@@ -62,12 +65,16 @@ unless(defined?(MonkeyCamels))
|
|
62
65
|
@__not_camel = false
|
63
66
|
self
|
64
67
|
end
|
68
|
+
|
65
69
|
alias_method :camel!, :_hump
|
66
70
|
|
67
71
|
# @return [Symbol, NilClass] style of hump
|
68
72
|
def _hump_style
|
69
|
-
@__hump_style
|
73
|
+
if defined?(@__hump_style)
|
74
|
+
@__hump_style
|
75
|
+
end
|
70
76
|
end
|
77
|
+
|
71
78
|
alias_method :hump_style!, :_hump_style
|
72
79
|
|
73
80
|
# Set hump style to non-leading upcase
|
@@ -78,6 +85,7 @@ unless(defined?(MonkeyCamels))
|
|
78
85
|
@__hump_style = :no_leading_hump
|
79
86
|
self
|
80
87
|
end
|
88
|
+
|
81
89
|
alias_method :bactrian!, :_bactrian
|
82
90
|
alias_method :no_leading_hump!, :_bactrian
|
83
91
|
|
@@ -89,26 +97,26 @@ unless(defined?(MonkeyCamels))
|
|
89
97
|
@__hump_style = :leading_hump
|
90
98
|
self
|
91
99
|
end
|
100
|
+
|
92
101
|
alias_method :dromedary!, :_dromedary
|
93
102
|
alias_method :leading_hump!, :_dromedary
|
94
|
-
|
95
103
|
end
|
96
|
-
|
97
104
|
end
|
98
105
|
|
99
106
|
# Force some monkeys around
|
100
|
-
String.send(:include, MonkeyCamels)
|
101
|
-
Symbol.send(:include, MonkeyCamels)
|
107
|
+
::String.send(:include, MonkeyCamels)
|
108
|
+
::Symbol.send(:include, MonkeyCamels)
|
102
109
|
|
103
110
|
# Specialized String type
|
104
|
-
class CamelString < String
|
105
|
-
def initialize(val=nil)
|
111
|
+
class CamelString < ::String
|
112
|
+
def initialize(val = nil)
|
106
113
|
super
|
107
|
-
if(val.respond_to?(:_camel?))
|
114
|
+
if (val.respond_to?(:_camel?))
|
108
115
|
_no_hump unless val._camel?
|
109
116
|
@__hump_style = val._hump_style
|
117
|
+
else
|
118
|
+
@__hump_style = nil
|
110
119
|
end
|
111
120
|
end
|
112
121
|
end
|
113
|
-
|
114
122
|
end
|
data/lib/attribute_struct.rb
CHANGED
@@ -1,8 +1,4 @@
|
|
1
|
-
require
|
2
|
-
require 'attribute_struct/attribute_struct'
|
1
|
+
require "bogo"
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
autoload :IrbCompat, 'attribute_struct/irb_compat'
|
7
|
-
|
8
|
-
require 'attribute_struct/version'
|
3
|
+
require "attribute_struct/attribute_struct"
|
4
|
+
require "attribute_struct/version"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attribute_struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bogo
|
@@ -30,6 +30,34 @@ dependencies:
|
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 0.3.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rspec
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '3.5'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '3.5'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '13'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '13'
|
33
61
|
- !ruby/object:Gem::Dependency
|
34
62
|
name: minitest
|
35
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,8 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
109
|
- !ruby/object:Gem::Version
|
82
110
|
version: '0'
|
83
111
|
requirements: []
|
84
|
-
|
85
|
-
rubygems_version: 2.4.8
|
112
|
+
rubygems_version: 3.4.0.dev
|
86
113
|
signing_key:
|
87
114
|
specification_version: 4
|
88
115
|
summary: Attribute structures
|