snaky_hash 1.0.1 → 2.0.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 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: