hanami-utils 2.0.0.alpha1 → 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 +4 -4
- data/CHANGELOG.md +216 -4
- data/README.md +16 -23
- data/hanami-utils.gemspec +6 -5
- data/lib/hanami/middleware.rb +10 -3
- data/lib/hanami/utils/blank.rb +7 -7
- data/lib/hanami/utils/callbacks.rb +4 -2
- data/lib/hanami/utils/class.rb +0 -31
- data/lib/hanami/utils/class_attribute.rb +7 -7
- data/lib/hanami/utils/escape.rb +172 -170
- data/lib/hanami/utils/file_list.rb +22 -2
- data/lib/hanami/utils/files.rb +13 -2
- data/lib/hanami/utils/hash.rb +20 -32
- data/lib/hanami/utils/json.rb +11 -1
- data/lib/hanami/utils/kernel.rb +14 -14
- data/lib/hanami/utils/load_paths.rb +3 -3
- data/lib/hanami/utils/path_prefix.rb +33 -3
- data/lib/hanami/utils/query_string.rb +1 -1
- data/lib/hanami/utils/shell_color.rb +14 -10
- data/lib/hanami/utils/string.rb +33 -394
- data/lib/hanami/utils/version.rb +3 -2
- data/lib/hanami/utils.rb +4 -4
- metadata +36 -21
- data/lib/hanami/interactor.rb +0 -619
- data/lib/hanami/logger/colorizer.rb +0 -105
- data/lib/hanami/logger/filter.rb +0 -68
- data/lib/hanami/logger/formatter.rb +0 -183
- data/lib/hanami/logger.rb +0 -360
- data/lib/hanami/utils/basic_object.rb +0 -84
data/lib/hanami/utils/hash.rb
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
3
|
+
require "dry/transformer"
|
|
4
4
|
|
|
5
5
|
module Hanami
|
|
6
6
|
module Utils
|
|
7
7
|
# Hash transformations
|
|
8
8
|
# @since 0.1.0
|
|
9
9
|
module Hash
|
|
10
|
-
extend
|
|
11
|
-
import
|
|
10
|
+
extend Dry::Transformer::Registry
|
|
11
|
+
import Dry::Transformer::HashTransformations
|
|
12
12
|
|
|
13
13
|
# Symbolize the given hash
|
|
14
14
|
#
|
|
@@ -32,7 +32,7 @@ module Hanami
|
|
|
32
32
|
self[:symbolize_keys].call(input)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
#
|
|
35
|
+
# Performs deep symbolize on the given hash
|
|
36
36
|
#
|
|
37
37
|
# @param input [::Hash] the input
|
|
38
38
|
#
|
|
@@ -54,7 +54,7 @@ module Hanami
|
|
|
54
54
|
self[:deep_symbolize_keys].call(input)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
#
|
|
57
|
+
# Stringifies the given hash
|
|
58
58
|
#
|
|
59
59
|
# @param input [::Hash] the input
|
|
60
60
|
#
|
|
@@ -74,7 +74,7 @@ module Hanami
|
|
|
74
74
|
self[:stringify_keys].call(input)
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
-
# Deeply
|
|
77
|
+
# Deeply stringifies the given hash
|
|
78
78
|
#
|
|
79
79
|
# @param input [::Hash] the input
|
|
80
80
|
#
|
|
@@ -90,31 +90,19 @@ module Hanami
|
|
|
90
90
|
#
|
|
91
91
|
# hash.class
|
|
92
92
|
# # => Hash
|
|
93
|
-
def self.deep_stringify(input)
|
|
94
|
-
|
|
95
|
-
output[key.to_s] =
|
|
96
|
-
case value
|
|
97
|
-
when ::Hash
|
|
98
|
-
deep_stringify(value)
|
|
99
|
-
when Array
|
|
100
|
-
value.map do |item|
|
|
101
|
-
item.is_a?(::Hash) ? deep_stringify(item) : item
|
|
102
|
-
end
|
|
103
|
-
else
|
|
104
|
-
value
|
|
105
|
-
end
|
|
106
|
-
end
|
|
93
|
+
def self.deep_stringify(input)
|
|
94
|
+
self[:deep_stringify_keys].call(input)
|
|
107
95
|
end
|
|
108
96
|
|
|
109
|
-
# Deep
|
|
97
|
+
# Deep duplicates hash values
|
|
110
98
|
#
|
|
111
|
-
# The output of this function is a
|
|
99
|
+
# The output of this function is a deep duplicate of the input.
|
|
112
100
|
# Any further modification on the input, won't be reflected on the output
|
|
113
101
|
# and viceversa.
|
|
114
102
|
#
|
|
115
103
|
# @param input [::Hash] the input
|
|
116
104
|
#
|
|
117
|
-
# @return [::Hash] the
|
|
105
|
+
# @return [::Hash] the deep duplicate of input
|
|
118
106
|
#
|
|
119
107
|
# @since 1.0.1
|
|
120
108
|
#
|
|
@@ -144,17 +132,17 @@ module Hanami
|
|
|
144
132
|
# input
|
|
145
133
|
# # => {"a"=>{"b"=>{"c"=>[1,2,3,4]}}}
|
|
146
134
|
def self.deep_dup(input)
|
|
147
|
-
input.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
135
|
+
input.transform_values do |v|
|
|
136
|
+
case v
|
|
137
|
+
when ::Hash
|
|
138
|
+
deep_dup(v)
|
|
139
|
+
else
|
|
140
|
+
v.dup
|
|
141
|
+
end
|
|
154
142
|
end
|
|
155
143
|
end
|
|
156
144
|
|
|
157
|
-
# Deep
|
|
145
|
+
# Deep serializes given object into a `Hash`
|
|
158
146
|
#
|
|
159
147
|
# Please note that the returning `Hash` will use symbols as keys.
|
|
160
148
|
#
|
|
@@ -178,7 +166,7 @@ module Hanami
|
|
|
178
166
|
#
|
|
179
167
|
# Hanami::Utils::Hash.deep_serialize(input)
|
|
180
168
|
# # => {:foo=>"bar", :baz=>[{:hello=>"world"}]}
|
|
181
|
-
def self.deep_serialize(input)
|
|
169
|
+
def self.deep_serialize(input)
|
|
182
170
|
input.to_hash.each_with_object({}) do |(key, value), output|
|
|
183
171
|
output[key.to_sym] =
|
|
184
172
|
case value
|
data/lib/hanami/utils/json.rb
CHANGED
|
@@ -35,15 +35,25 @@ module Hanami
|
|
|
35
35
|
|
|
36
36
|
# rubocop:disable Style/ClassVars
|
|
37
37
|
if defined?(MultiJson)
|
|
38
|
+
# @since 0.8.0
|
|
39
|
+
# @api private
|
|
38
40
|
@@engine = MultiJsonAdapter.new
|
|
41
|
+
|
|
42
|
+
# @since 0.8.0
|
|
43
|
+
# @api private
|
|
39
44
|
ParserError = MultiJson::ParseError
|
|
40
45
|
else
|
|
46
|
+
# @since 0.8.0
|
|
47
|
+
# @api private
|
|
41
48
|
@@engine = ::JSON
|
|
49
|
+
|
|
50
|
+
# @since 0.8.0
|
|
51
|
+
# @api private
|
|
42
52
|
ParserError = ::JSON::ParserError
|
|
43
53
|
end
|
|
44
54
|
# rubocop:enable Style/ClassVars
|
|
45
55
|
|
|
46
|
-
#
|
|
56
|
+
# Parses the given JSON paylod
|
|
47
57
|
#
|
|
48
58
|
# @param payload [String] a JSON payload
|
|
49
59
|
#
|
data/lib/hanami/utils/kernel.rb
CHANGED
|
@@ -5,11 +5,12 @@ require "date"
|
|
|
5
5
|
require "time"
|
|
6
6
|
require "pathname"
|
|
7
7
|
require "bigdecimal"
|
|
8
|
+
require "bigdecimal/util"
|
|
8
9
|
require "hanami/utils"
|
|
9
10
|
require "hanami/utils/string"
|
|
10
11
|
|
|
11
12
|
unless defined?(Boolean)
|
|
12
|
-
#
|
|
13
|
+
# Defines top level constant Boolean, so it can be easily used by other libraries
|
|
13
14
|
# in coercions DSLs
|
|
14
15
|
#
|
|
15
16
|
# @since 0.3.0
|
|
@@ -28,7 +29,7 @@ module Hanami
|
|
|
28
29
|
# @api private
|
|
29
30
|
#
|
|
30
31
|
# @see Hanami::Utils::Kernel.Integer
|
|
31
|
-
NUMERIC_MATCHER = %r{\A([\d
|
|
32
|
+
NUMERIC_MATCHER = %r{\A([\d/.+iE]+|NaN|Infinity)\z}
|
|
32
33
|
|
|
33
34
|
# @since 0.8.0
|
|
34
35
|
# @api private
|
|
@@ -327,7 +328,7 @@ module Hanami
|
|
|
327
328
|
# # big complex represented as a string
|
|
328
329
|
# input = Complex(2, 3)
|
|
329
330
|
# Hanami::Utils::Kernel.Integer(input) # => TypeError
|
|
330
|
-
def self.Integer(arg)
|
|
331
|
+
def self.Integer(arg)
|
|
331
332
|
super(arg)
|
|
332
333
|
rescue ArgumentError, TypeError, NoMethodError
|
|
333
334
|
begin
|
|
@@ -418,7 +419,6 @@ module Hanami
|
|
|
418
419
|
# input = BasicObject.new
|
|
419
420
|
# Hanami::Utils::Kernel.BigDecimal(input) # => TypeError
|
|
420
421
|
#
|
|
421
|
-
# rubocop:disable Metrics/MethodLength
|
|
422
422
|
def self.BigDecimal(arg, precision = ::Float::DIG)
|
|
423
423
|
case arg
|
|
424
424
|
when NilClass # This is only needed by Ruby 2.6
|
|
@@ -435,7 +435,6 @@ module Hanami
|
|
|
435
435
|
rescue NoMethodError
|
|
436
436
|
raise TypeError.new "can't convert #{inspect_type_error(arg)}into BigDecimal"
|
|
437
437
|
end
|
|
438
|
-
# rubocop:enable Metrics/MethodLength
|
|
439
438
|
|
|
440
439
|
# Coerces the argument to be a Float.
|
|
441
440
|
#
|
|
@@ -549,7 +548,7 @@ module Hanami
|
|
|
549
548
|
# # big complex represented as a string
|
|
550
549
|
# input = Complex(2, 3)
|
|
551
550
|
# Hanami::Utils::Kernel.Float(input) # => TypeError
|
|
552
|
-
def self.Float(arg)
|
|
551
|
+
def self.Float(arg)
|
|
553
552
|
super(arg)
|
|
554
553
|
rescue ArgumentError, TypeError
|
|
555
554
|
begin
|
|
@@ -738,7 +737,8 @@ module Hanami
|
|
|
738
737
|
# require 'hanami/utils/kernel'
|
|
739
738
|
#
|
|
740
739
|
# Hanami::Utils::Kernel.DateTime(3483943)
|
|
741
|
-
# # => Time.at(3483943).to_datetime
|
|
740
|
+
# # => Time.at(3483943).to_datetime
|
|
741
|
+
# # #<DateTime: 1970-02-10T08:45:43+01:00 ((2440628j,27943s,0n),+3600s,2299161j)>
|
|
742
742
|
#
|
|
743
743
|
# Hanami::Utils::Kernel.DateTime(DateTime.now)
|
|
744
744
|
# # => #<DateTime: 2014-04-18T09:33:49+02:00 ((2456766j,27229s,690849000n),+7200s,2299161j)>
|
|
@@ -898,7 +898,7 @@ module Hanami
|
|
|
898
898
|
# # Missing #respond_to?
|
|
899
899
|
# input = BasicObject.new
|
|
900
900
|
# Hanami::Utils::Kernel.Boolean(input) # => TypeError
|
|
901
|
-
def self.Boolean(arg)
|
|
901
|
+
def self.Boolean(arg)
|
|
902
902
|
case arg
|
|
903
903
|
when Numeric
|
|
904
904
|
arg.to_i == BOOLEAN_TRUE_INTEGER
|
|
@@ -1016,14 +1016,14 @@ module Hanami
|
|
|
1016
1016
|
case arg
|
|
1017
1017
|
when "" then raise TypeError.new "can't convert #{inspect_type_error(arg)}into Symbol"
|
|
1018
1018
|
when ->(a) { a.respond_to?(:to_sym) } then arg.to_sym
|
|
1019
|
-
else
|
|
1019
|
+
else # rubocop:disable Lint/DuplicateBranch
|
|
1020
1020
|
raise TypeError.new "can't convert #{inspect_type_error(arg)}into Symbol"
|
|
1021
1021
|
end
|
|
1022
1022
|
rescue NoMethodError
|
|
1023
1023
|
raise TypeError.new "can't convert #{inspect_type_error(arg)}into Symbol"
|
|
1024
1024
|
end
|
|
1025
1025
|
|
|
1026
|
-
#
|
|
1026
|
+
# Checks if the given argument is a string representation of a number
|
|
1027
1027
|
#
|
|
1028
1028
|
# @param arg [Object] the input
|
|
1029
1029
|
#
|
|
@@ -1044,11 +1044,11 @@ module Hanami
|
|
|
1044
1044
|
# @since 0.4.3
|
|
1045
1045
|
# @api private
|
|
1046
1046
|
def self.inspect_type_error(arg)
|
|
1047
|
-
|
|
1048
|
-
rescue NoMethodError
|
|
1047
|
+
"#{arg.respond_to?(:inspect) ? arg.inspect : arg.to_s} "
|
|
1048
|
+
rescue NoMethodError
|
|
1049
1049
|
# missing the #respond_to? method, fall back to returning the class' name
|
|
1050
1050
|
begin
|
|
1051
|
-
arg.class.name
|
|
1051
|
+
"#{arg.class.name} instance "
|
|
1052
1052
|
rescue NoMethodError
|
|
1053
1053
|
# missing the #class method, can't fall back to anything better than nothing
|
|
1054
1054
|
# Callers will have to guess from their code
|
|
@@ -1057,7 +1057,7 @@ module Hanami
|
|
|
1057
1057
|
end
|
|
1058
1058
|
|
|
1059
1059
|
class << self
|
|
1060
|
-
private :inspect_type_error
|
|
1060
|
+
private :inspect_type_error
|
|
1061
1061
|
end
|
|
1062
1062
|
end
|
|
1063
1063
|
end
|
|
@@ -50,7 +50,7 @@ module Hanami
|
|
|
50
50
|
@paths = original.instance_variable_get(:@paths).dup
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
# Iterates
|
|
53
|
+
# Iterates through the collection and yields the given block.
|
|
54
54
|
# It skips duplications and raises an error in case one of the paths
|
|
55
55
|
# doesn't exist.
|
|
56
56
|
#
|
|
@@ -117,7 +117,7 @@ module Hanami
|
|
|
117
117
|
self
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
alias_method :<<, :push
|
|
121
121
|
|
|
122
122
|
# It freezes the object by preventing further modifications.
|
|
123
123
|
#
|
|
@@ -158,7 +158,7 @@ module Hanami
|
|
|
158
158
|
|
|
159
159
|
private
|
|
160
160
|
|
|
161
|
-
#
|
|
161
|
+
# Allows subclasses to define their own policy to discover the realpath
|
|
162
162
|
# of the given path.
|
|
163
163
|
#
|
|
164
164
|
# @since 0.2.0
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "hanami/utils/string"
|
|
4
3
|
require "hanami/utils/kernel"
|
|
5
4
|
|
|
6
5
|
module Hanami
|
|
@@ -8,7 +7,7 @@ module Hanami
|
|
|
8
7
|
# Prefixed string
|
|
9
8
|
#
|
|
10
9
|
# @since 0.1.0
|
|
11
|
-
class PathPrefix
|
|
10
|
+
class PathPrefix
|
|
12
11
|
# Path separator
|
|
13
12
|
#
|
|
14
13
|
# @since 0.3.1
|
|
@@ -26,7 +25,7 @@ module Hanami
|
|
|
26
25
|
#
|
|
27
26
|
# @see Hanami::Utils::PathPrefix::DEFAULT_SEPARATOR
|
|
28
27
|
def initialize(string = nil, separator = DEFAULT_SEPARATOR)
|
|
29
|
-
|
|
28
|
+
@string = string.to_s
|
|
30
29
|
@separator = separator
|
|
31
30
|
end
|
|
32
31
|
|
|
@@ -93,6 +92,37 @@ module Hanami
|
|
|
93
92
|
).relative!
|
|
94
93
|
end
|
|
95
94
|
|
|
95
|
+
# Returns the hash of the internal string
|
|
96
|
+
#
|
|
97
|
+
# @return [Integer]
|
|
98
|
+
#
|
|
99
|
+
# @since 0.3.0
|
|
100
|
+
def hash
|
|
101
|
+
@string.hash
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Returns a string representation
|
|
105
|
+
#
|
|
106
|
+
# @return [::String]
|
|
107
|
+
#
|
|
108
|
+
# @since 0.3.0
|
|
109
|
+
def to_s
|
|
110
|
+
@string
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
alias_method :to_str, :to_s
|
|
114
|
+
|
|
115
|
+
# Equality
|
|
116
|
+
#
|
|
117
|
+
# @return [TrueClass,FalseClass]
|
|
118
|
+
#
|
|
119
|
+
# @since 0.3.0
|
|
120
|
+
def ==(other)
|
|
121
|
+
to_s == other
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
alias_method :eql?, :==
|
|
125
|
+
|
|
96
126
|
protected
|
|
97
127
|
|
|
98
128
|
# Modifies the path prefix to have a prepended separator.
|
|
@@ -7,33 +7,37 @@ module Hanami
|
|
|
7
7
|
# It doesn't check if you're writing to a file or anything, so you have to
|
|
8
8
|
# check that yourself before using this module.
|
|
9
9
|
#
|
|
10
|
+
# @api public
|
|
10
11
|
# @since 1.2.0
|
|
11
12
|
module ShellColor
|
|
12
|
-
#
|
|
13
|
+
# Error raised for unknown color codes.
|
|
13
14
|
#
|
|
14
15
|
# @since 1.2.0
|
|
16
|
+
# @api public
|
|
15
17
|
class UnknownColorCodeError < ::StandardError
|
|
18
|
+
# @since 1.2.0
|
|
19
|
+
# @api private
|
|
16
20
|
def initialize(code)
|
|
17
21
|
super("unknown color code: `#{code.inspect}'")
|
|
18
22
|
end
|
|
19
23
|
end
|
|
20
24
|
|
|
21
|
-
#
|
|
25
|
+
# Escapes codes for terminals to output strings in colors
|
|
22
26
|
#
|
|
23
27
|
# @since 1.2.0
|
|
24
28
|
# @api private
|
|
25
29
|
COLORS = ::Hash[
|
|
26
|
-
black:
|
|
27
|
-
red:
|
|
28
|
-
green:
|
|
29
|
-
yellow:
|
|
30
|
-
blue:
|
|
30
|
+
black: 30,
|
|
31
|
+
red: 31,
|
|
32
|
+
green: 32,
|
|
33
|
+
yellow: 33,
|
|
34
|
+
blue: 34,
|
|
31
35
|
magenta: 35,
|
|
32
|
-
cyan:
|
|
33
|
-
gray:
|
|
36
|
+
cyan: 36,
|
|
37
|
+
gray: 37,
|
|
34
38
|
].freeze
|
|
35
39
|
|
|
36
|
-
#
|
|
40
|
+
# Colorizes output
|
|
37
41
|
# 8 colors available: black, red, green, yellow, blue, magenta, cyan, and gray
|
|
38
42
|
#
|
|
39
43
|
# @param input [#to_s] the string to colorize
|