attribute_struct 0.2.28 → 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/CHANGELOG.md +25 -20
- data/LICENSE +1 -1
- data/README.md +225 -35
- data/lib/attribute_struct/attribute_struct.rb +41 -16
- data/lib/attribute_struct/monkey_camels.rb +3 -3
- data/lib/attribute_struct/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8589e76432a36f05a1450f97e802269ef8edb8df
|
4
|
+
data.tar.gz: 6364945c9d3ccb645eb54e2a419675a7d4f2ad61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bf46e3d433e2718593b6981303a88226b38aff6b421028d1b23f79fb7bdf765a7f800a2c0d35a4d33323f17f3a2a33f73b201d8aee88fec0b68aa1b4757d8b6
|
7
|
+
data.tar.gz: e26b766049f6bd19ba1b9e54bae280ae97372d5b438ee15bd1c44f97d8d20b2c802461a9f14721a3eaa98ee65f83f9a4a412fbe2faee590b4b980ff97aed05e1
|
data/CHANGELOG.md
CHANGED
@@ -1,80 +1,85 @@
|
|
1
|
-
|
1
|
+
# v0.3.0
|
2
|
+
* Only allow forced key processing when camel casing is enabled
|
3
|
+
* Refactored dump implementation to better handle deeply nested structs
|
4
|
+
* Add missing bang method aliases
|
5
|
+
|
6
|
+
# v0.2.28
|
2
7
|
* Set internal data at creation time, not after evaluation
|
3
8
|
|
4
|
-
|
9
|
+
# v0.2.26
|
5
10
|
* Add support for lowercase leading camel casing
|
6
11
|
|
7
|
-
|
12
|
+
# v0.2.24
|
8
13
|
* Fix `#_root` helper to properly check for parent
|
9
14
|
* Always use the `#_klass_new` helper
|
10
15
|
* Support optional arguments/block to `#_klass_new`
|
11
16
|
|
12
|
-
|
17
|
+
# v0.2.22
|
13
18
|
* Add more helper method bang aliases
|
14
19
|
* Properly persist camel data on Hash keys
|
15
20
|
* Support optional automatic AttributeStruct loading on Hash set
|
16
21
|
|
17
|
-
|
22
|
+
# v0.2.20
|
18
23
|
* Fix: remove nil structs
|
19
24
|
|
20
|
-
|
25
|
+
# v0.2.18
|
21
26
|
* Fix `AttributeStruct#dump!` to properly handle nil-type values
|
22
27
|
|
23
|
-
|
28
|
+
# v0.2.16
|
24
29
|
* Fix regression mixed argument and block set returning second level struct
|
25
30
|
|
26
|
-
|
31
|
+
# v0.2.14
|
27
32
|
* Fix `:value_collapse` option to prevent multiple nestings
|
28
33
|
|
29
|
-
|
34
|
+
# v0.2.12
|
30
35
|
* Implementation updates to monkey camels helper
|
31
36
|
* Provide bang style helper methods for all helpers
|
32
37
|
|
33
|
-
|
38
|
+
# v0.2.10
|
34
39
|
* Add support for multi parameter set
|
35
40
|
|
36
|
-
|
41
|
+
# v0.2.8
|
37
42
|
* Fix class mismatch issue
|
38
43
|
|
39
|
-
|
44
|
+
# v0.2.6
|
40
45
|
* Vendor `Mash` and expand to provide required deep_merge functionality
|
41
46
|
* Remove external dependencies
|
42
47
|
|
43
|
-
|
48
|
+
# v0.2.4
|
44
49
|
* Revert #class method removal (required by hash helpers when duping)
|
45
50
|
* Set base prior to path walking
|
46
51
|
* Initialize struct if nil is encountered
|
47
52
|
* Collapse values at leaf
|
48
53
|
|
49
|
-
|
54
|
+
# v0.2.2
|
50
55
|
* Update block evaluation assignment to prevent value knockout
|
51
56
|
* Fix `#is_a?` behavior and include base class in check list
|
52
57
|
* Add `#respond_to?` method
|
53
58
|
* Add irb helper module
|
54
59
|
|
55
|
-
|
60
|
+
# v0.2.0
|
56
61
|
* Add support for value setting into given context level
|
57
62
|
* Add #build helper method
|
58
63
|
* Introduce `:value_collapse` option for multi set combination instead of replacement
|
59
64
|
* Provide bang suffix aliases
|
60
65
|
|
61
|
-
|
66
|
+
# v0.1.8
|
62
67
|
* Basic (optional) auto camel detection on import
|
63
68
|
* Add hash helper methods out to class
|
64
69
|
|
65
|
-
|
70
|
+
# v0.1.6
|
66
71
|
* Add helpers for walking up the tree
|
67
72
|
* Update hashie dependency restriction
|
68
73
|
|
69
|
-
|
74
|
+
# v0.1.4
|
70
75
|
* Add `_array` helper
|
71
76
|
* Ensure all helpers are using underscore prefix
|
72
77
|
* Inherit from BasicObject
|
73
78
|
* Allow struct discovery in enumerable objects
|
74
79
|
* Add more helpers
|
75
80
|
|
76
|
-
|
81
|
+
# v0.1.2
|
77
82
|
* Fix naming in require
|
78
83
|
|
79
|
-
|
84
|
+
# v0.1.0
|
80
85
|
* Initial release
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,66 +1,256 @@
|
|
1
1
|
# AttributeStruct
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
more robust, and provide extra features.
|
3
|
+
AttributeStruct is a DSL helper library. It provides support for programmatic
|
4
|
+
generation of complex data structures.
|
6
5
|
|
7
|
-
##
|
6
|
+
## How it works
|
8
7
|
|
9
|
-
|
8
|
+
Under the hood, AttributeStruct makes use of Ruby's `BasicObject` class and the
|
9
|
+
`#method_missing` method to bring a clean and concise way of generating data
|
10
|
+
structures. Deeply nested Hashes can be built using method chaining, block
|
11
|
+
structures, or both. Evaluation of a structure is performed top down, allowing
|
12
|
+
access to previously set data values within the structure during evaluation.
|
10
13
|
|
11
|
-
##
|
14
|
+
## Examples
|
15
|
+
|
16
|
+
### Setting values
|
17
|
+
|
18
|
+
#### Method chaining
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
require 'attribute_struct'
|
22
|
+
|
23
|
+
AttributeStruct.new do
|
24
|
+
this.is.a.deeply.nested.hash true
|
25
|
+
end.dump!
|
26
|
+
|
27
|
+
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>true}}}}}}
|
28
|
+
```
|
29
|
+
|
30
|
+
#### Block nesting
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
require 'attribute_struct'
|
34
|
+
|
35
|
+
AttributeStruct.new do
|
36
|
+
this do
|
37
|
+
is do
|
38
|
+
a do
|
39
|
+
deeply do
|
40
|
+
nested do
|
41
|
+
hash true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end.dump!
|
48
|
+
|
49
|
+
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>true}}}}}}
|
50
|
+
```
|
51
|
+
|
52
|
+
#### Mixed block nesting and method chaining
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
require 'attribute_struct'
|
56
|
+
|
57
|
+
AttributeStruct.new do
|
58
|
+
this.is.a do
|
59
|
+
deeply.nested do
|
60
|
+
hash true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end.dump!
|
64
|
+
|
65
|
+
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>true}}}}}}
|
66
|
+
```
|
67
|
+
|
68
|
+
### Structure re-entry
|
69
|
+
|
70
|
+
#### Block re-entry
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
require 'attribute_struct'
|
74
|
+
|
75
|
+
AttributeStruct.new do
|
76
|
+
this.is.a do
|
77
|
+
deeply.nested do
|
78
|
+
hash true
|
79
|
+
end
|
80
|
+
deeply do
|
81
|
+
nested.other_hash true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end.dump!
|
85
|
+
|
86
|
+
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>true,"other_hash"=>true}}}}}}
|
87
|
+
```
|
88
|
+
|
89
|
+
#### Method re-entry
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
require 'attribute_struct'
|
93
|
+
|
94
|
+
AttributeStruct.new do
|
95
|
+
this.is.a do
|
96
|
+
deeply.nested do
|
97
|
+
hash true
|
98
|
+
end
|
99
|
+
end
|
100
|
+
this.is.a.deeply.nested.other_hash true
|
101
|
+
end.dump!
|
102
|
+
|
103
|
+
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>true,"other_hash"=>true}}}}}}
|
104
|
+
```
|
105
|
+
|
106
|
+
### Data removal
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
require 'attribute_struct'
|
110
|
+
|
111
|
+
AttributeStruct.new do
|
112
|
+
this.is.a do
|
113
|
+
deeply.nested do
|
114
|
+
hash true
|
115
|
+
end
|
116
|
+
end
|
117
|
+
this.is.a.deeply.nested.other_hash true
|
118
|
+
this.is.a.deeply.nested.delete!(:hash)
|
119
|
+
end.dump!
|
120
|
+
|
121
|
+
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"other_hash"=>true}}}}}}
|
122
|
+
```
|
123
|
+
|
124
|
+
### Data Access
|
125
|
+
|
126
|
+
#### Current data
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
require 'attribute_struct'
|
130
|
+
|
131
|
+
AttributeStruct.new do
|
132
|
+
this.is.a do
|
133
|
+
deeply.nested do
|
134
|
+
hash 'my_value'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
this.is.a.deeply.nested do
|
138
|
+
other_hash data![:hash]
|
139
|
+
end
|
140
|
+
end.dump!
|
141
|
+
|
142
|
+
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>"my_value","other_hash"=>"my_value"}}}}}}
|
143
|
+
```
|
144
|
+
|
145
|
+
#### Current data keys
|
12
146
|
|
13
147
|
```ruby
|
14
148
|
require 'attribute_struct'
|
15
149
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
bind '*'
|
150
|
+
AttributeStruct.new do
|
151
|
+
this.is.a do
|
152
|
+
deeply.nested do
|
153
|
+
hash 'my_value'
|
154
|
+
end
|
22
155
|
end
|
23
|
-
|
24
|
-
|
25
|
-
port 80
|
26
|
-
bind '*'
|
156
|
+
this.is.a.deeply.nested do
|
157
|
+
other_hash keys!
|
27
158
|
end
|
28
|
-
|
29
|
-
|
159
|
+
end.dump!
|
160
|
+
|
161
|
+
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nested"=>{"hash"=>"my_value","other_hash"=>["hash"]}}}}}}
|
162
|
+
```
|
163
|
+
|
164
|
+
### Hierarchy access
|
165
|
+
|
166
|
+
#### Parent structure
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
require 'attribute_struct'
|
170
|
+
|
171
|
+
AttributeStruct.new do
|
172
|
+
this.is.a do
|
173
|
+
deeply do
|
174
|
+
state 'sunny'
|
175
|
+
nested do
|
176
|
+
hash parent!.state
|
177
|
+
end
|
178
|
+
end
|
30
179
|
end
|
31
|
-
end
|
180
|
+
end.dump!
|
181
|
+
|
182
|
+
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"state"=>"sunny", "nested"=>{"hash"=>"sunny"}}}}}}
|
32
183
|
```
|
33
184
|
|
34
|
-
|
35
|
-
query and modify. To force it to a hash, we
|
36
|
-
can simply dump it:
|
185
|
+
#### Root structure
|
37
186
|
|
38
187
|
```ruby
|
39
|
-
require '
|
188
|
+
require 'attribute_struct'
|
189
|
+
|
190
|
+
AttributeStruct.new do
|
191
|
+
this.is.a do
|
192
|
+
deeply do
|
193
|
+
state 'sunny'
|
194
|
+
nested do
|
195
|
+
hash root!.this.is.a.deeply.state
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end.dump!
|
40
200
|
|
41
|
-
|
201
|
+
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"state"=>"sunny", "nested"=>{"hash"=>"sunny"}}}}}}
|
42
202
|
```
|
43
203
|
|
44
|
-
|
204
|
+
### Camel case
|
205
|
+
|
206
|
+
#### Camel case keys
|
45
207
|
|
46
208
|
```ruby
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
209
|
+
require 'attribute_struct'
|
210
|
+
|
211
|
+
AttributeStruct.new do
|
212
|
+
self._camel_keys = true
|
213
|
+
this.is.a.deeply.nested_camel.hash true
|
214
|
+
end.dump!
|
215
|
+
|
216
|
+
# => {"This"=>{"Is"=>{"A"=>{"Deeply"=>{"NestedCamel"=>{"Hash"=>true}}}}}}
|
52
217
|
```
|
53
218
|
|
54
|
-
|
219
|
+
#### Camel case with lead lower
|
220
|
+
|
221
|
+
```ruby
|
222
|
+
require 'attribute_struct'
|
223
|
+
|
224
|
+
AttributeStruct.new do
|
225
|
+
self._camel_keys = true
|
226
|
+
self._camel_style = :no_leading
|
227
|
+
this.is.a.deeply.nested_camel.hash true
|
228
|
+
end.dump!
|
55
229
|
|
56
|
-
|
57
|
-
|
230
|
+
# => {"this"=>{"is"=>{"a"=>{"deeply"=>{"nestedCamel"=>{"hash"=>true}}}}}}
|
231
|
+
```
|
232
|
+
|
233
|
+
#### Disable camel on individual key
|
58
234
|
|
59
235
|
```ruby
|
60
|
-
|
61
|
-
|
236
|
+
require 'attribute_struct'
|
237
|
+
|
238
|
+
AttributeStruct.new do
|
239
|
+
self._camel_keys = true
|
240
|
+
this.is.a.deeply.nested_camel.hash true
|
241
|
+
this.set!('horse'.no_hump!, true)
|
242
|
+
end.dump!
|
243
|
+
|
244
|
+
# => {"This"=>{"Is"=>{"A"=>{"Deeply"=>{"NestedCamel"=>{"Hash"=>true}}}}},"horse" => true}
|
62
245
|
```
|
63
246
|
|
247
|
+
## In the wild
|
248
|
+
|
249
|
+
Libraries utilizing AttributeStruct:
|
250
|
+
|
251
|
+
* SparkleFormation: http://www.sparkleformation.io
|
252
|
+
* Bogo Config: https://github.com/spox/bogo-config
|
253
|
+
|
64
254
|
## Information
|
65
255
|
|
66
256
|
* Repo: https://github.com/chrisroberts/attribute_struct
|
@@ -8,7 +8,7 @@ class AttributeStruct < BasicObject
|
|
8
8
|
|
9
9
|
# @return [Hash] valid styles and mapped value
|
10
10
|
VALID_CAMEL_STYLES = {
|
11
|
-
:
|
11
|
+
:bactrian => :no_leading,
|
12
12
|
:no_leading_hump => :no_leading,
|
13
13
|
:no_leading => :no_leading,
|
14
14
|
:dromedary => :leading,
|
@@ -87,10 +87,13 @@ class AttributeStruct < BasicObject
|
|
87
87
|
|
88
88
|
# @return [Truthy, Falsey] current camelizing setting
|
89
89
|
attr_reader :_camel_keys
|
90
|
+
alias_method :camel_keys!, :_camel_keys
|
90
91
|
# @return [Symbol] current camel style
|
91
92
|
attr_reader :_camel_style
|
93
|
+
alias_method :camel_style!, :_camel_style
|
92
94
|
# @return [AtributeStruct::AttributeHash, Mash] holding space for state
|
93
95
|
attr_reader :_arg_state
|
96
|
+
alias_method :arg_state!, :_arg_state
|
94
97
|
|
95
98
|
# Create new instance
|
96
99
|
#
|
@@ -300,6 +303,11 @@ class AttributeStruct < BasicObject
|
|
300
303
|
_data.empty?
|
301
304
|
end
|
302
305
|
|
306
|
+
# @return [TrueClass, FalseClass] struct is present (not empty)
|
307
|
+
def present?
|
308
|
+
!nil?
|
309
|
+
end
|
310
|
+
|
303
311
|
# Determine if self is a class
|
304
312
|
#
|
305
313
|
# @param klass [Class]
|
@@ -330,22 +338,39 @@ class AttributeStruct < BasicObject
|
|
330
338
|
end
|
331
339
|
alias_method :delete!, :_delete
|
332
340
|
|
333
|
-
#
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
341
|
+
# Process and unpack items for dumping within deeply nested
|
342
|
+
# enumerable types
|
343
|
+
#
|
344
|
+
# @param item [Object]
|
345
|
+
# @return [Object]
|
346
|
+
def _dump_unpacker(item)
|
347
|
+
if(item.is_a?(::Enumerable))
|
348
|
+
if(item.respond_to?(:keys))
|
349
|
+
item.class[
|
350
|
+
*item.map do |entry|
|
351
|
+
_dump_unpacker(entry)
|
352
|
+
end.flatten(1)
|
353
|
+
]
|
345
354
|
else
|
346
|
-
|
355
|
+
item.class[
|
356
|
+
*item.map do |entry|
|
357
|
+
_dump_unpacker(entry)
|
358
|
+
end
|
359
|
+
]
|
347
360
|
end
|
348
|
-
|
361
|
+
elsif(item.is_a?(::AttributeStruct))
|
362
|
+
item.nil? ? :__unset__ : item._dump
|
363
|
+
else
|
364
|
+
item
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
# @return [AttributeStruct::AttributeHash, Mash] dump struct to hashish
|
369
|
+
def _dump
|
370
|
+
processed = @table.keys.map do |key|
|
371
|
+
value = @table[key]
|
372
|
+
val = _dump_unpacker(value)
|
373
|
+
[_dump_unpacker(key), val] unless val == :__unset__
|
349
374
|
end.compact
|
350
375
|
__hashish[*processed.flatten(1)]
|
351
376
|
end
|
@@ -453,7 +478,7 @@ class AttributeStruct < BasicObject
|
|
453
478
|
key._hump
|
454
479
|
end
|
455
480
|
end
|
456
|
-
if(
|
481
|
+
if(_camel_keys && (key._camel? || args.include?(:force)))
|
457
482
|
camel_args = [key]
|
458
483
|
if(key._hump_style || _camel_style == :no_leading)
|
459
484
|
unless(key._hump_style == :leading_hump)
|
@@ -73,13 +73,13 @@ unless(defined?(MonkeyCamels))
|
|
73
73
|
# Set hump style to non-leading upcase
|
74
74
|
#
|
75
75
|
# @return [self]
|
76
|
-
def
|
76
|
+
def _bactrian
|
77
77
|
@__not_camel = false
|
78
78
|
@__hump_style = :no_leading_hump
|
79
79
|
self
|
80
80
|
end
|
81
|
-
alias_method :
|
82
|
-
alias_method :no_leading_hump!, :
|
81
|
+
alias_method :bactrian!, :_bactrian
|
82
|
+
alias_method :no_leading_hump!, :_bactrian
|
83
83
|
|
84
84
|
# Set hump style to leading upcase
|
85
85
|
#
|
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.3.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: 2016-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bogo
|