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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cfc06b7c06365d662bcdad2368dff79f50dfc8e3
4
- data.tar.gz: c9bfd8626aafcdbeae1502078eb6da1cd8da5a70
3
+ metadata.gz: 035249bf5d64b998b482081c145889b8631b4a41
4
+ data.tar.gz: 6ea2dcf26bb6fa926811d4ff751c871c0bc1e8f5
5
5
  SHA512:
6
- metadata.gz: 890d86ec18d079d1e21c646bf68d7ba88f5cabda369eac76b48092b6050fc2760eb3ad081645551551d11141d8ff4cf9b50aab849f24b68c101cdb7edc5d2163
7
- data.tar.gz: fdd854a130baf3b73dd56f75550d1ab35b343861fc8ca75d30976e3f8cfefbb90bd0f0e0f5c6cad7d3fe6b640d79651e3b16a3cde6abb2d3e07e0dcc0cdeba5a
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
- hm = HashMangler::Mangler.new(value_mangler: value_mangler).mangle(hash)
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 `snake_case_method_names: false` option needs to be passed into `initialize`:
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
- hm = HashMangler::Mangler.new(snake_case_method_names: false).mangle(hash)
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
@@ -1,3 +1,3 @@
1
1
  module HashMangler
2
- VERSION = "0.2.0"
2
+ VERSION = '0.3.2'.freeze
3
3
  end
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.0
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-13 00:00:00.000000000 Z
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: