tins 1.52.0 → 1.53.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/CHANGES.md +15 -0
- data/lib/tins/hash_symbolize_keys_recursive.rb +37 -6
- data/lib/tins/token.rb +2 -2
- data/lib/tins/version.rb +1 -1
- data/tests/hash_symbolize_keys_recursive_test.rb +57 -1
- data/tins.gemspec +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7878ad969917b7fe9cb5ecdd474c612c5a440434331b3036729000b42ba26f7a
|
|
4
|
+
data.tar.gz: c0a7b9b5d3f69b19ed6ef11de637e70a286324089bf12f28c555502af1d7b775
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 240db7924b97b15d7e8df113407fd3878f08911caf4c4b362569a6fb563ca49d6a7ffa2227ea9ff8180fb5b321e174def7799b9c147b6b29a8d5fde6e2d14f7a
|
|
7
|
+
data.tar.gz: c5f3a1447cf33d250f5819895d59cc74bd4168b0bccc49371cde8efdd377c54ae98a554e30ac817d7c5d597e92dea3c0c0b37e2ad3b6b058e390613db50a25a6
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-04-14 v1.53.0
|
|
4
|
+
|
|
5
|
+
- Added `stringify_keys_recursive` and `stringify_keys_recursive!` methods to convert hash keys from symbols to strings
|
|
6
|
+
- Renamed `_symbolize_keys_recursive` to `_transform_keys_recursive` to
|
|
7
|
+
support both `:to_sym` and `:to_s` transformations
|
|
8
|
+
- Updated `symbolize_keys_recursive` to use the new
|
|
9
|
+
`_transform_keys_recursive` with `transform: :to_sym`
|
|
10
|
+
- Added comprehensive tests for the new `stringify_keys_recursive` methods
|
|
11
|
+
including circular reference handling
|
|
12
|
+
- Updated YARD documentation for all new and modified methods
|
|
13
|
+
- Made `Token#bits` immutable from outside by changing `attr_accessor
|
|
14
|
+
:bits` to `attr_reader :bits` and using direct instance variable
|
|
15
|
+
assignment
|
|
16
|
+
- Bump `s.rubygems_version` from **4.0.3** to **4.0.10** in `tins.gemspec`
|
|
17
|
+
|
|
3
18
|
## 2026-02-23 v1.52.0
|
|
4
19
|
|
|
5
20
|
- Renamed `BASE32_EXTENDED_HEX_ALPHABET` to
|
|
@@ -49,7 +49,23 @@ module Tins
|
|
|
49
49
|
# # => { name: "John", self: "[Circular]" }
|
|
50
50
|
def symbolize_keys_recursive(circular: nil)
|
|
51
51
|
self.seen = {}
|
|
52
|
-
|
|
52
|
+
_transform_keys_recursive(self, circular: circular, transform: :to_sym)
|
|
53
|
+
ensure
|
|
54
|
+
self.seen = nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Converts all keys in the hash (and nested hashes) to strings.
|
|
58
|
+
#
|
|
59
|
+
# @param circular [Object] The value to return for circular references.
|
|
60
|
+
# @return [Hash] A new hash with all keys converted to strings.
|
|
61
|
+
#
|
|
62
|
+
# @example
|
|
63
|
+
# hash = { name: "John", address: { city: "NYC" } }
|
|
64
|
+
# hash.stringify_keys_recursive
|
|
65
|
+
# # => { "name" => "John", "address" => { "city" => "NYC" } }
|
|
66
|
+
def stringify_keys_recursive(circular: nil)
|
|
67
|
+
self.seen = {}
|
|
68
|
+
_transform_keys_recursive(self, circular: circular, transform: :to_s)
|
|
53
69
|
ensure
|
|
54
70
|
self.seen = nil
|
|
55
71
|
end
|
|
@@ -70,14 +86,28 @@ module Tins
|
|
|
70
86
|
replace symbolize_keys_recursive(circular: circular)
|
|
71
87
|
end
|
|
72
88
|
|
|
89
|
+
# Converts all keys in the hash (and nested hashes) to strings in place.
|
|
90
|
+
#
|
|
91
|
+
# @param circular [Object] The value to return for circular references.
|
|
92
|
+
# @return [Hash] The same hash with all keys converted to strings.
|
|
93
|
+
#
|
|
94
|
+
# @example
|
|
95
|
+
# hash = { name: "John", address: { city: "NYC" } }
|
|
96
|
+
# hash.stringify_keys_recursive!
|
|
97
|
+
# # => { "name" => "John", "address" => { "city" => "NYC" } }
|
|
98
|
+
def stringify_keys_recursive!(circular: nil)
|
|
99
|
+
replace stringify_keys_recursive(circular: circular)
|
|
100
|
+
end
|
|
101
|
+
|
|
73
102
|
private
|
|
74
103
|
|
|
75
|
-
# Performs the actual recursive
|
|
104
|
+
# Performs the actual recursive transformation work
|
|
76
105
|
#
|
|
77
106
|
# @param object [Object] The object to process
|
|
78
107
|
# @param circular [Object] The value to return for circular references
|
|
79
|
-
# @
|
|
80
|
-
|
|
108
|
+
# @param transform [Symbol] The transformation to apply to keys (`:to_sym` or `:to_s`).
|
|
109
|
+
# @return [Object] The processed object with transformed keys
|
|
110
|
+
def _transform_keys_recursive(object, circular: nil, transform:)
|
|
81
111
|
case
|
|
82
112
|
when seen[object.__id__]
|
|
83
113
|
object = circular
|
|
@@ -87,7 +117,8 @@ module Tins
|
|
|
87
117
|
new_object = object.class.new
|
|
88
118
|
seen[new_object.__id__] = true
|
|
89
119
|
object.each do |k, v|
|
|
90
|
-
new_object[k.to_s.
|
|
120
|
+
new_object[k.to_s.__send__(transform)] =
|
|
121
|
+
_transform_keys_recursive(v, circular: circular, transform:)
|
|
91
122
|
end
|
|
92
123
|
object = new_object
|
|
93
124
|
when object.respond_to?(:to_ary)
|
|
@@ -96,7 +127,7 @@ module Tins
|
|
|
96
127
|
new_object = object.class.new(object.size)
|
|
97
128
|
seen[new_object.__id__] = true
|
|
98
129
|
object.each_with_index do |v, i|
|
|
99
|
-
new_object[i] =
|
|
130
|
+
new_object[i] = _transform_keys_recursive(v, circular: circular, transform:)
|
|
100
131
|
end
|
|
101
132
|
object = new_object
|
|
102
133
|
end
|
data/lib/tins/token.rb
CHANGED
|
@@ -87,7 +87,7 @@ module Tins
|
|
|
87
87
|
bits > 0 or raise ArgumentError, 'bits has to be positive'
|
|
88
88
|
length = (Math.log(1 << bits) / Math.log(alphabet.size)).ceil
|
|
89
89
|
end
|
|
90
|
-
|
|
90
|
+
@bits = self.class.analyze(alphabet:, length:)
|
|
91
91
|
token = +''
|
|
92
92
|
length.times { token << alphabet[random.random_number(alphabet.size)] }
|
|
93
93
|
super token
|
|
@@ -96,7 +96,7 @@ module Tins
|
|
|
96
96
|
# The bit length of the token.
|
|
97
97
|
#
|
|
98
98
|
# @return [Integer] the number of bits of entropy in the token
|
|
99
|
-
|
|
99
|
+
attr_reader :bits
|
|
100
100
|
|
|
101
101
|
# The analyze method calculates the bit length of a token based on its
|
|
102
102
|
# alphabet and length.
|
data/lib/tins/version.rb
CHANGED
|
@@ -59,5 +59,61 @@ module Tins
|
|
|
59
59
|
hash.symbolize_keys_recursive(circular: :circular)
|
|
60
60
|
)
|
|
61
61
|
end
|
|
62
|
+
|
|
63
|
+
def test_stringify
|
|
64
|
+
hash = {
|
|
65
|
+
:key => [
|
|
66
|
+
{
|
|
67
|
+
:key => {
|
|
68
|
+
:key => true
|
|
69
|
+
},
|
|
70
|
+
:o => Object.new,
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
}
|
|
74
|
+
hash2 = hash.stringify_keys_recursive
|
|
75
|
+
assert hash2["key"][0]["key"]["key"]
|
|
76
|
+
hash.stringify_keys_recursive!
|
|
77
|
+
assert hash["key"][0]["key"]["key"]
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_stringify_bang
|
|
81
|
+
hash = { :foo => 'bar' }
|
|
82
|
+
hash.stringify_keys_recursive!
|
|
83
|
+
assert_equal({ "foo" => 'bar' }, hash)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_stringify_with_circular_array
|
|
87
|
+
circular_array = [].tap { |a| a << a }
|
|
88
|
+
assert_equal(
|
|
89
|
+
{ "foo" => [ nil ] },
|
|
90
|
+
{ :foo => circular_array }.stringify_keys_recursive
|
|
91
|
+
)
|
|
92
|
+
assert_equal(
|
|
93
|
+
{ "foo" => [ :circular ] },
|
|
94
|
+
{ :foo => circular_array }.stringify_keys_recursive(circular: :circular)
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def test_stringify_with_circular_hash
|
|
99
|
+
circular_hash = {}.tap { |h| h[:foo] = h }
|
|
100
|
+
circular_hash_string = {}.tap { |h| h['foo'] = nil }
|
|
101
|
+
assert_equal(
|
|
102
|
+
{ "bar" => circular_hash_string },
|
|
103
|
+
{ :bar => circular_hash }.stringify_keys_recursive
|
|
104
|
+
)
|
|
105
|
+
assert_equal(
|
|
106
|
+
{ "bar" => { "foo" => :circular } },
|
|
107
|
+
{ :bar => circular_hash }.stringify_keys_recursive(circular: :circular)
|
|
108
|
+
)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def test_stringify_deeper_nesting
|
|
112
|
+
hash = { :foo => [ true, [ { :bar => {}.tap { |h| h[:foo] = h } }, 3.141, [].tap { |arr| arr << arr } ] ] }
|
|
113
|
+
assert_equal(
|
|
114
|
+
{"foo"=> [true, [{"bar"=> {"foo"=> :circular}}, 3.141, [:circular]]]},
|
|
115
|
+
hash.stringify_keys_recursive(circular: :circular)
|
|
116
|
+
)
|
|
117
|
+
end
|
|
62
118
|
end
|
|
63
|
-
end
|
|
119
|
+
end
|
data/tins.gemspec
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# stub: tins 1.
|
|
2
|
+
# stub: tins 1.53.0 ruby lib
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "tins".freeze
|
|
6
|
-
s.version = "1.
|
|
6
|
+
s.version = "1.53.0".freeze
|
|
7
7
|
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
9
9
|
s.require_paths = ["lib".freeze]
|
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
|
17
17
|
s.licenses = ["MIT".freeze]
|
|
18
18
|
s.rdoc_options = ["--title".freeze, "Tins - Useful stuff.".freeze, "--main".freeze, "README.md".freeze]
|
|
19
19
|
s.required_ruby_version = Gem::Requirement.new(">= 3.1".freeze)
|
|
20
|
-
s.rubygems_version = "4.0.
|
|
20
|
+
s.rubygems_version = "4.0.10".freeze
|
|
21
21
|
s.summary = "Useful stuff.".freeze
|
|
22
22
|
s.test_files = ["tests/annotate_test.rb".freeze, "tests/ask_and_send_test.rb".freeze, "tests/attempt_test.rb".freeze, "tests/bijection_test.rb".freeze, "tests/blank_full_test.rb".freeze, "tests/case_predicate_test.rb".freeze, "tests/concern_test.rb".freeze, "tests/date_dummy_test.rb".freeze, "tests/date_time_dummy_test.rb".freeze, "tests/deep_dup_test.rb".freeze, "tests/delegate_test.rb".freeze, "tests/deprecate_test.rb".freeze, "tests/dslkit_test.rb".freeze, "tests/duration_test.rb".freeze, "tests/dynamic_scope_test.rb".freeze, "tests/expose_test.rb".freeze, "tests/extract_last_argument_options_test.rb".freeze, "tests/file_binary_test.rb".freeze, "tests/find_test.rb".freeze, "tests/from_module_test.rb".freeze, "tests/generator_test.rb".freeze, "tests/go_test.rb".freeze, "tests/hash_bfs_test.rb".freeze, "tests/hash_dfs_test.rb".freeze, "tests/hash_symbolize_keys_recursive_test.rb".freeze, "tests/hash_union_test.rb".freeze, "tests/if_predicate_test.rb".freeze, "tests/implement_test.rb".freeze, "tests/limited_test.rb".freeze, "tests/lines_file_test.rb".freeze, "tests/lru_cache_test.rb".freeze, "tests/memoize_test.rb".freeze, "tests/method_description_test.rb".freeze, "tests/minimize_test.rb".freeze, "tests/module_group_test.rb".freeze, "tests/named_set_test.rb".freeze, "tests/named_test.rb".freeze, "tests/null_test.rb".freeze, "tests/p_test.rb".freeze, "tests/partial_application_test.rb".freeze, "tests/proc_compose_test.rb".freeze, "tests/proc_prelude_test.rb".freeze, "tests/range_plus_test.rb".freeze, "tests/require_maybe_test.rb".freeze, "tests/responding_test.rb".freeze, "tests/rotate_test.rb".freeze, "tests/scope_test.rb".freeze, "tests/secure_write_test.rb".freeze, "tests/sexy_singleton_test.rb".freeze, "tests/string_byte_order_mark_test.rb".freeze, "tests/string_camelize_test.rb".freeze, "tests/string_named_placeholders.rb".freeze, "tests/string_underscore_test.rb".freeze, "tests/string_version_test.rb".freeze, "tests/subhash_test.rb".freeze, "tests/temp_io_test.rb".freeze, "tests/test_helper.rb".freeze, "tests/time_dummy_test.rb".freeze, "tests/time_freezer_test.rb".freeze, "tests/to_test.rb".freeze, "tests/token_test.rb".freeze, "tests/unit_test.rb".freeze, "tests/annotate_test.rb".freeze, "tests/ask_and_send_test.rb".freeze, "tests/attempt_test.rb".freeze, "tests/bijection_test.rb".freeze, "tests/blank_full_test.rb".freeze, "tests/case_predicate_test.rb".freeze, "tests/concern_test.rb".freeze, "tests/date_dummy_test.rb".freeze, "tests/date_time_dummy_test.rb".freeze, "tests/deep_dup_test.rb".freeze, "tests/delegate_test.rb".freeze, "tests/deprecate_test.rb".freeze, "tests/dslkit_test.rb".freeze, "tests/duration_test.rb".freeze, "tests/dynamic_scope_test.rb".freeze, "tests/expose_test.rb".freeze, "tests/extract_last_argument_options_test.rb".freeze, "tests/file_binary_test.rb".freeze, "tests/find_test.rb".freeze, "tests/from_module_test.rb".freeze, "tests/generator_test.rb".freeze, "tests/go_test.rb".freeze, "tests/hash_bfs_test.rb".freeze, "tests/hash_dfs_test.rb".freeze, "tests/hash_symbolize_keys_recursive_test.rb".freeze, "tests/hash_union_test.rb".freeze, "tests/if_predicate_test.rb".freeze, "tests/implement_test.rb".freeze, "tests/limited_test.rb".freeze, "tests/lines_file_test.rb".freeze, "tests/lru_cache_test.rb".freeze, "tests/memoize_test.rb".freeze, "tests/method_description_test.rb".freeze, "tests/minimize_test.rb".freeze, "tests/module_group_test.rb".freeze, "tests/named_set_test.rb".freeze, "tests/named_test.rb".freeze, "tests/null_test.rb".freeze, "tests/p_test.rb".freeze, "tests/partial_application_test.rb".freeze, "tests/proc_compose_test.rb".freeze, "tests/proc_prelude_test.rb".freeze, "tests/range_plus_test.rb".freeze, "tests/require_maybe_test.rb".freeze, "tests/responding_test.rb".freeze, "tests/rotate_test.rb".freeze, "tests/scope_test.rb".freeze, "tests/secure_write_test.rb".freeze, "tests/sexy_singleton_test.rb".freeze, "tests/string_byte_order_mark_test.rb".freeze, "tests/string_camelize_test.rb".freeze, "tests/string_underscore_test.rb".freeze, "tests/string_version_test.rb".freeze, "tests/subhash_test.rb".freeze, "tests/temp_io_test.rb".freeze, "tests/time_dummy_test.rb".freeze, "tests/time_freezer_test.rb".freeze, "tests/to_test.rb".freeze, "tests/token_test.rb".freeze, "tests/unit_test.rb".freeze]
|
|
23
23
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tins
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.53.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -503,7 +503,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
503
503
|
- !ruby/object:Gem::Version
|
|
504
504
|
version: '0'
|
|
505
505
|
requirements: []
|
|
506
|
-
rubygems_version: 4.0.
|
|
506
|
+
rubygems_version: 4.0.10
|
|
507
507
|
specification_version: 4
|
|
508
508
|
summary: Useful stuff.
|
|
509
509
|
test_files:
|