hash_mangler 0.2.0 → 0.3.2
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/README.md +37 -4
- data/lib/hash_mangler.rb +1 -49
- data/lib/hash_mangler/mangler.rb +35 -0
- data/lib/hash_mangler/mangler/key_mangler.rb +44 -0
- data/lib/hash_mangler/simple_struct.rb +30 -0
- data/lib/hash_mangler/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 035249bf5d64b998b482081c145889b8631b4a41
|
|
4
|
+
data.tar.gz: 6ea2dcf26bb6fa926811d4ff751c871c0bc1e8f5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 65ffd3c1d0db077659beb1b61db8ab389d9766e036fbe508d2aee8a4978fb0c36e6d63911c566577947b58acb59c01d2a41443bcff33f7989db118f816d1a28e
|
|
7
|
+
data.tar.gz: 6964318e0595e3a05fad54c4699ed859808350326a7559431dfd234cce32c5e0c76af610c8fe8ff44d0da46dcf4738b15cdf9210bccab53f0aa70d314a6f8a8b
|
data/README.md
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
# HashMangler
|
|
2
2
|
|
|
3
3
|
A simple gem which converts nested hash into a struct allowing data access with method calls like:
|
|
4
|
+
|
|
4
5
|
```
|
|
5
6
|
mangled_hash.users[0].name # => John
|
|
6
7
|
```
|
|
8
|
+
|
|
7
9
|
instead of doing:
|
|
10
|
+
|
|
8
11
|
```
|
|
9
12
|
users_hash[:users][0].fetch(:name) # => John
|
|
10
13
|
```
|
|
14
|
+
|
|
11
15
|
for a hash:
|
|
16
|
+
|
|
12
17
|
```
|
|
13
18
|
users_hash = {
|
|
14
19
|
users: [
|
|
@@ -38,26 +43,54 @@ Or install it yourself as:
|
|
|
38
43
|
## Usage
|
|
39
44
|
|
|
40
45
|
For a basic convertion from Hash to a nested object:
|
|
46
|
+
|
|
47
|
+
|
|
41
48
|
```
|
|
42
49
|
hm = HashMangler::Mangler.new.mangle(hash)
|
|
43
50
|
hm.some_method_name
|
|
44
51
|
```
|
|
45
52
|
|
|
46
53
|
You can also perform operations on argument hash values by passing a proc to the `initialize` method:
|
|
54
|
+
|
|
47
55
|
```
|
|
48
56
|
value_mangler = proc { |o| o.to_s.downcase }
|
|
49
|
-
|
|
57
|
+
options = { value_mangler: value_mangler }
|
|
58
|
+
hm = HashMangler::Mangler.new(options).mangle(hash)
|
|
50
59
|
hm.some_method_name
|
|
51
60
|
```
|
|
52
61
|
|
|
53
|
-
If you want you can use `HashMangler::SimpleStruct` instead of `OpenStruct` when using `JSON.parse(json, object_class: OpenStruct)`. This way a `NoMethodError` will be raised instead of returning `nil` when method name does not comply with
|
|
54
62
|
|
|
55
|
-
By default method names are in snake case, to leave them the same as input hash keys
|
|
63
|
+
By default method names are in snake case, to leave them the same as input hash keys:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
snake_case_method_names: false
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
option needs to be passed into `initialize` like:
|
|
70
|
+
|
|
56
71
|
```
|
|
57
|
-
|
|
72
|
+
options = { snake_case_method_names: false }
|
|
73
|
+
hm = HashMangler::Mangler.new(options).mangle(hash)
|
|
58
74
|
hm.someMethodName
|
|
59
75
|
```
|
|
60
76
|
|
|
77
|
+
Hash can also be mangled with `OpenStruct` or `Hash` using `struct_class` option:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
options = { struct_class: OpenStruct }
|
|
81
|
+
hm = HashMangler::Mangler.new(options).mangle(hash)
|
|
82
|
+
hm.some_method_name
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`HashMangler::SimpleStruct` can also be used instead of `OpenStruct` when using:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
JSON.parse(json, object_class: OpenStruct)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
This way a `NoMethodError` will be raised instead of returning `nil` when method name does not comply with
|
|
92
|
+
|
|
93
|
+
|
|
61
94
|
## Contributing
|
|
62
95
|
|
|
63
96
|
Bug reports and pull requests are welcome on GitHub at https://github.com/smnkrt/hash_mangler.
|
data/lib/hash_mangler.rb
CHANGED
|
@@ -1,53 +1,5 @@
|
|
|
1
1
|
require 'hash_mangler/version'
|
|
2
|
+
require 'hash_mangler/mangler'
|
|
2
3
|
|
|
3
4
|
module HashMangler
|
|
4
|
-
class SimpleStruct
|
|
5
|
-
def initialize(snake_case_method_names = true)
|
|
6
|
-
@snake_case_method_names = snake_case_method_names
|
|
7
|
-
@hash = {}
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def []=(key, val)
|
|
11
|
-
key = format_key(key)
|
|
12
|
-
@hash[key] = val
|
|
13
|
-
define_singleton_method(key) { @hash[key] }
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def [](key)
|
|
17
|
-
@hash[format_key(key)]
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
def format_key(key)
|
|
23
|
-
return key unless @snake_case_method_names
|
|
24
|
-
key_to_snake_case(key)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def key_to_snake_case(key)
|
|
28
|
-
key
|
|
29
|
-
.to_s
|
|
30
|
-
.gsub(/::/, '/')
|
|
31
|
-
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
32
|
-
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
33
|
-
.tr('-', '_')
|
|
34
|
-
.downcase
|
|
35
|
-
.to_sym
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
class Mangler
|
|
40
|
-
def initialize(options = {})
|
|
41
|
-
@snake_case_method_names = options.fetch(:snake_case_method_names, true)
|
|
42
|
-
@value_mangler = options.fetch(:value_mangler, proc { |o| o })
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def mangle(a)
|
|
46
|
-
return @value_mangler.(a) unless a.is_a?(Hash) || a.is_a?(Array)
|
|
47
|
-
return a.map { |v| mangle(v) } if a.is_a?(Array)
|
|
48
|
-
r = HashMangler::SimpleStruct.new(@snake_case_method_names)
|
|
49
|
-
a.each { |k, v| r[k] = mangle(v) }
|
|
50
|
-
r
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
5
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require_relative 'mangler/key_mangler'
|
|
2
|
+
require_relative 'simple_struct'
|
|
3
|
+
|
|
4
|
+
module HashMangler
|
|
5
|
+
class Mangler
|
|
6
|
+
#
|
|
7
|
+
# @param options [Hash]
|
|
8
|
+
# @option options [Boolean] :snake_case_method_names specifies if generated method
|
|
9
|
+
# names should be formatted to snake case, defaults to: true
|
|
10
|
+
# @option options [Proc] :value_mangler optional proc called for each leaf value
|
|
11
|
+
# defaults to: proc { |o| o }
|
|
12
|
+
# @option options [Class] :struct_class optional class which will be used to convert
|
|
13
|
+
# hash data into object, defaults to: HashMangler::SimpleStruct
|
|
14
|
+
# any class with [](key) and []=(key, value) accessor methods
|
|
15
|
+
#
|
|
16
|
+
def initialize(options = {})
|
|
17
|
+
@value_mangler = options.fetch(:value_mangler, proc { |o| o })
|
|
18
|
+
@struct_class = options.fetch(:struct_class , HashMangler::SimpleStruct)
|
|
19
|
+
@key_mangler = KeyMangler.new(options)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
# @param obj (Object) for which mangling should be performed
|
|
24
|
+
# it should respond to []= and [] methods
|
|
25
|
+
# @return [struct_class]
|
|
26
|
+
#
|
|
27
|
+
def mangle(obj)
|
|
28
|
+
return @value_mangler.call(obj) unless obj.is_a?(Hash) || obj.is_a?(Array)
|
|
29
|
+
return obj.map { |v| mangle(v) } if obj.is_a?(Array)
|
|
30
|
+
r = @struct_class.new()
|
|
31
|
+
obj.each { |k, v| r[@key_mangler.format(k)] = mangle(v) }
|
|
32
|
+
r
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module HashMangler
|
|
2
|
+
class Mangler
|
|
3
|
+
class KeyMangler
|
|
4
|
+
#
|
|
5
|
+
# @param options [Hash]
|
|
6
|
+
# @option options [Boolean] :snake_case_method_names specifies if generated method
|
|
7
|
+
# names should be formatted to snake case, defaults to: true
|
|
8
|
+
#
|
|
9
|
+
def initialize(options)
|
|
10
|
+
@snake_case_method_names = options.fetch(:snake_case_method_names, true)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# formats key to snake case if @snake_case_method_names is true,
|
|
15
|
+
# otherwise returns key as a symbol
|
|
16
|
+
# @param key [Symbol/String]
|
|
17
|
+
# @return [Symbol]
|
|
18
|
+
#
|
|
19
|
+
def format(key)
|
|
20
|
+
return key.to_sym unless @snake_case_method_names
|
|
21
|
+
key_to_snake_case(key)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# @params key
|
|
28
|
+
# @return [Symbol] key in snake case
|
|
29
|
+
#
|
|
30
|
+
def key_to_snake_case(key)
|
|
31
|
+
key
|
|
32
|
+
.to_s
|
|
33
|
+
.gsub(/::/, '/')
|
|
34
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
35
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
36
|
+
.tr('-', '_')
|
|
37
|
+
.downcase
|
|
38
|
+
.to_sym
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private_constant :KeyMangler
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module HashMangler
|
|
2
|
+
#
|
|
3
|
+
# Simple object defining singleton methods for each (key, value) pair
|
|
4
|
+
# passed into []=(key, val) method.
|
|
5
|
+
#
|
|
6
|
+
class SimpleStruct
|
|
7
|
+
def initialize
|
|
8
|
+
@hash = {}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# sets value for provided key and generates a singleton method
|
|
13
|
+
# @param key [String/Symbol]
|
|
14
|
+
# a passed value (val) will be available
|
|
15
|
+
# @param val [Object]
|
|
16
|
+
#
|
|
17
|
+
def []=(key, val)
|
|
18
|
+
@hash[key] = val
|
|
19
|
+
define_singleton_method(key) { @hash[key] }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#
|
|
23
|
+
# retrieves value for provided key
|
|
24
|
+
# @param key [String/Symbol]
|
|
25
|
+
#
|
|
26
|
+
def [](key)
|
|
27
|
+
@hash[key]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/hash_mangler/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hash_mangler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2
|
|
4
|
+
version: 0.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- smnkrt
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-05-
|
|
11
|
+
date: 2017-05-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -83,6 +83,9 @@ files:
|
|
|
83
83
|
- Rakefile
|
|
84
84
|
- hash_mangler.gemspec
|
|
85
85
|
- lib/hash_mangler.rb
|
|
86
|
+
- lib/hash_mangler/mangler.rb
|
|
87
|
+
- lib/hash_mangler/mangler/key_mangler.rb
|
|
88
|
+
- lib/hash_mangler/simple_struct.rb
|
|
86
89
|
- lib/hash_mangler/version.rb
|
|
87
90
|
homepage: https://github.com/smnkrt/hash_mangler
|
|
88
91
|
licenses:
|