snaky_hash 1.0.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e99b35c24440f1bdfff52d7df4819b0d3aa662bdbe22a6d71d1c80830229fc92
4
- data.tar.gz: 9fa5b0c87bda98373f1fd2361aca7f5288dd37ab813f868a405dfdffc72a43b8
3
+ metadata.gz: 5995aa841b28557864f23d3d2e08c861d5854805c8eb8bed7e68719b89412a44
4
+ data.tar.gz: 035cd4ab1644739be5ab0bfcea8388bc37110e4cd4b3d495b70715652bd3cd35
5
5
  SHA512:
6
- metadata.gz: 731ec98f1d8eb0538a1b707ac09bbc7ddc18489993a332a872d2e1115d5d46d0c0a814d71729788fbd01a3b01990402d60116d321aa385a745970b67ca6ce364
7
- data.tar.gz: 671f10410a228e0989e940da413c6a13ce8404d315393cef59b9b043db05c7574afae1835c43a9728d06e81f15a9f64f01ec1c36f50d0a6564d8c703cea74a96
6
+ metadata.gz: b2ee23b5884158fe2642c73b2d00665900e509a606942008cc2e02aee79becd46d01f71e16e4702d027f9961cbd24f5892ecf4bf06915344def299b4488f9324
7
+ data.tar.gz: fa72da01cb55b92152f9274f3dcb2920c6948d73ed11d0d3af70cfa86b713985b73746e3a8b60f0cf8873e8fea62dbd4dcc9d659e329ccbaad32ff901052ea34
data/CHANGELOG.md CHANGED
@@ -12,6 +12,18 @@ and this project adheres to [Semantic Versioning v2](https://semver.org/spec/v2.
12
12
 
13
13
  ## [Unreleased]
14
14
 
15
+ ## [2.0.0] - 2022-08-29
16
+ ### Changed
17
+ - **BREAKING**: `SnakeHash::Snake` is now a mixin, now with support for symbol or string keys
18
+ ```ruby
19
+ class MySnakedHash < Hashie::Mash
20
+ include SnakyHash::Snake.new(key_type: :string) # or :symbol
21
+ end
22
+ ```
23
+ ### Added
24
+ - `SnakyHash::StringKeyed`: a Hashie::Mash class with snake-cased String keys
25
+ - `SnakyHash::SymbolKeyed`: a Hashie::Mash class with snake-cased Symbol keys
26
+
15
27
  ## [1.0.1] - 2022-08-26
16
28
  ### Added
17
29
  - Missing LICENSE.txt file to release
data/README.md CHANGED
@@ -5,7 +5,7 @@ and provide a nice psuedo-object interface.
5
5
 
6
6
  It has its roots in the `Rash` (specifically the [`rash_alt`](https://github.com/shishi/rash_alt) flavor), which is a special `Mash`, made popular by the `hashie` gem.
7
7
 
8
- `SnakyHash::Snake` does inherit from `Hashie::Mash` and adds some additional behaviors.
8
+ Classes that include `SnakyHash::Snake` should inherit from `Hashie::Mash`.
9
9
 
10
10
  ## Installation
11
11
 
@@ -19,7 +19,45 @@ If bundler is not being used to manage dependencies, install the gem by executin
19
19
 
20
20
  ## Usage
21
21
 
22
- For now, please see specs
22
+ ```ruby
23
+ class MySnakedHash < Hashie::Mash
24
+ include SnakyHash::Snake.new(key_type: :string) # or :symbol
25
+ end
26
+
27
+ snake = MySnakedHash.new(a: 'a', 'b' => 'b', 2 => 2, 'VeryFineHat' => 'Feathers')
28
+ snake.a # => 'a'
29
+ snake.b # => 'b'
30
+ snake[2] # 2
31
+ snake.very_fine_hat # => 'Feathers'
32
+ snake[:very_fine_hat] # => 'Feathers'
33
+ snake['very_fine_hat'] # => 'Feathers'
34
+ ```
35
+
36
+ Note above that you can access the values via the string, or symbol.
37
+ The `key_type` determines how the key is actually stored, but the hash acts as "indifferent".
38
+ Note also that keys which do not respond to `to_sym`, because they don't have a natural conversion to a Symbol,
39
+ are left as-is.
40
+
41
+ ### Stranger Things
42
+
43
+ I don't recommend using these features... but they exist (for now).
44
+ You can still access the original un-snaked camel keys.
45
+ And through them you can even use un-snaked camel methods.
46
+
47
+ ```ruby
48
+ snake.key?('VeryFineHat') # => true
49
+ snake['VeryFineHat'] # => 'Feathers'
50
+ snake.VeryFineHat # => 'Feathers', PLEASE don't do this!!!
51
+ snake['VeryFineHat'] = 'pop' # Please don't do this... you'll get a warning, and it works (for now), but no guarantees.
52
+ # WARN -- : You are setting a key that conflicts with a built-in method MySnakedHash#VeryFineHat defined in MySnakedHash. This can cause unexpected behavior when accessing the key as a property. You can still access the key via the #[] method.
53
+ # => "pop"
54
+ snake.very_fine_hat = 'pop' # => 'pop', do this instead!!!
55
+ snake.very_fine_hat # => 'pop'
56
+ snake[:very_fine_hat] = 'moose' # => 'moose', or do this instead!!!
57
+ snake.very_fine_hat # => 'moose'
58
+ snake['very_fine_hat'] = 'cheese' # => 'cheese', or do this instead!!!
59
+ snake.very_fine_hat # => 'cheese'
60
+ ```
23
61
 
24
62
  ## Development
25
63
 
@@ -1,51 +1,72 @@
1
- require "hashie/mash"
2
-
1
+ # This is a module-class hybrid.
2
+ #
3
+ # Hashie's standard SymbolizeKeys is similar to the functionality we want.
4
+ # ... but not quite. We need to support both String (for oauth2) and Symbol keys (for oauth).
5
+ # include Hashie::Extensions::Mash::SymbolizeKeys
3
6
  module SnakyHash
4
- class Snake < Hashie::Mash
5
- # This is similar to the functionality we want.
6
- # include Hashie::Extensions::Mash::SymbolizeKeys
7
-
8
- protected
9
-
10
- # Converts a key to a string,
11
- # but only if it is able to be converted to a symbol.
12
- #
13
- # @api private
14
- # @param [<K>] key the key to attempt convert to a symbol
15
- # @return [String, K]
16
- def convert_key(key)
17
- key.respond_to?(:to_sym) ? underscore_string(key.to_s) : key
7
+ class Snake < Module
8
+ def initialize(key_type: :string)
9
+ super()
10
+ @key_type = key_type
18
11
  end
19
12
 
20
- # Unlike its parent Mash, a SnakyHash::Snake will convert other
21
- # Hashie::Hash values to a SnakyHash::Snake when assigning
22
- # instead of respecting the existing subclass
23
- def convert_value(val, duping = false) #:nodoc:
24
- case val
25
- when self.class
26
- val.dup
27
- when ::Hash
28
- val = val.dup if duping
29
- self.class.new(val)
30
- when ::Array
31
- val.collect { |e| convert_value(e) }
32
- else
33
- val
34
- end
13
+ def included(base)
14
+ conversions_module = SnakyModulizer.to_mod(@key_type)
15
+ base.include(conversions_module)
35
16
  end
36
17
 
37
- # converts a camel_cased string to a underscore string
38
- # subs spaces with underscores, strips whitespace
39
- # Same way ActiveSupport does string.underscore
40
- def underscore_string(str)
41
- str.to_s.strip
42
- .tr(" ", "_")
43
- .gsub(/::/, "/")
44
- .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
45
- .gsub(/([a-z\d])([A-Z])/, '\1_\2')
46
- .tr("-", "_")
47
- .squeeze("_")
48
- .downcase
18
+ module SnakyModulizer
19
+ def self.to_mod(key_type)
20
+ Module.new do
21
+ # Converts a key to a symbol, or a string, depending on key_type,
22
+ # but only if it is able to be converted to a symbol,
23
+ # and after underscoring it.
24
+ #
25
+ # @api private
26
+ # @param [<K>] key the key to attempt convert to a symbol
27
+ # @return [Symbol, K]
28
+
29
+ case key_type
30
+ when :string then
31
+ define_method(:convert_key) { |key| key.respond_to?(:to_sym) ? underscore_string(key.to_s) : key }
32
+ when :symbol then
33
+ define_method(:convert_key) { |key| key.respond_to?(:to_sym) ? underscore_string(key.to_s).to_sym : key }
34
+ else
35
+ raise ArgumentError, "SnakyHash: Unhandled key_type: #{key_type}"
36
+ end
37
+
38
+ # Unlike its parent Mash, a SnakyHash::Snake will convert other
39
+ # Hashie::Hash values to a SnakyHash::Snake when assigning
40
+ # instead of respecting the existing subclass
41
+ define_method :convert_value do |val, duping = false| #:nodoc:
42
+ case val
43
+ when self.class
44
+ val.dup
45
+ when ::Hash
46
+ val = val.dup if duping
47
+ self.class.new(val)
48
+ when ::Array
49
+ val.collect { |e| convert_value(e) }
50
+ else
51
+ val
52
+ end
53
+ end
54
+
55
+ # converts a camel_cased string to a underscore string
56
+ # subs spaces with underscores, strips whitespace
57
+ # Same way ActiveSupport does string.underscore
58
+ define_method :underscore_string do |str|
59
+ str.to_s.strip
60
+ .tr(" ", "_")
61
+ .gsub(/::/, "/")
62
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
63
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
64
+ .tr("-", "_")
65
+ .squeeze("_")
66
+ .downcase
67
+ end
68
+ end
69
+ end
49
70
  end
50
71
  end
51
72
  end
@@ -0,0 +1,5 @@
1
+ module SnakyHash
2
+ class StringKeyed < Hashie::Mash
3
+ include SnakyHash::Snake.new(key_type: :string)
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module SnakyHash
2
+ class SymbolKeyed < Hashie::Mash
3
+ include SnakyHash::Snake.new(key_type: :symbol)
4
+ end
5
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module SnakyHash
4
4
  module Version
5
- VERSION = "1.0.1".freeze
5
+ VERSION = "2.0.0".freeze
6
6
  end
7
7
  end
data/lib/snaky_hash.rb CHANGED
@@ -6,7 +6,10 @@ require "version_gem"
6
6
 
7
7
  require_relative "snaky_hash/version"
8
8
  require_relative "snaky_hash/snake"
9
+ require_relative "snaky_hash/string_keyed"
10
+ require_relative "snaky_hash/symbol_keyed"
9
11
 
12
+ # This is the namespace for this gem
10
13
  module SnakyHash
11
14
  end
12
15
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snaky_hash
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-08-26 00:00:00.000000000 Z
11
+ date: 2022-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '8.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-block_is_expected
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description: 'A Hashie::Mash joint to make #snakelife better'
84
98
  email:
85
99
  - peter.boling@gmail.com
@@ -95,16 +109,18 @@ files:
95
109
  - SECURITY.md
96
110
  - lib/snaky_hash.rb
97
111
  - lib/snaky_hash/snake.rb
112
+ - lib/snaky_hash/string_keyed.rb
113
+ - lib/snaky_hash/symbol_keyed.rb
98
114
  - lib/snaky_hash/version.rb
99
115
  homepage: https://gitlab.com/oauth-xx/snaky_hash
100
116
  licenses:
101
117
  - MIT
102
118
  metadata:
103
119
  homepage_uri: https://gitlab.com/oauth-xx/snaky_hash
104
- source_code_uri: https://gitlab.com/oauth-xx/snaky_hash/-/tree/v1.0.1
105
- changelog_uri: https://gitlab.com/oauth-xx/snaky_hash/-/blob/v1.0.1/CHANGELOG.md
120
+ source_code_uri: https://gitlab.com/oauth-xx/snaky_hash/-/tree/v2.0.0
121
+ changelog_uri: https://gitlab.com/oauth-xx/snaky_hash/-/blob/v2.0.0/CHANGELOG.md
106
122
  bug_tracker_uri: https://gitlab.com/oauth-xx/snaky_hash/-/issues
107
- documentation_uri: https://www.rubydoc.info/gems/snaky_hash/1.0.1
123
+ documentation_uri: https://www.rubydoc.info/gems/snaky_hash/2.0.0
108
124
  wiki_uri: https://gitlab.com/oauth-xx/snaky_hash/-/wikis/home
109
125
  rubygems_mfa_required: 'true'
110
126
  post_install_message: