env_parser 0.7.0 → 0.8.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.
@@ -52,6 +52,22 @@
52
52
  </li>
53
53
 
54
54
 
55
+ <li class="even ">
56
+ <div class="item">
57
+ <span class='object_link'><a href="EnvParser.html#define_type-class_method" title="EnvParser.define_type (method)">define_type</a></span>
58
+ <small>EnvParser</small>
59
+ </div>
60
+ </li>
61
+
62
+
63
+ <li class="odd ">
64
+ <div class="item">
65
+ <span class='object_link'><a href="top-level-namespace.html#filename-instance_method" title="#filename (method)">#filename</a></span>
66
+ <small>Top Level Namespace</small>
67
+ </div>
68
+ </li>
69
+
70
+
55
71
  <li class="even ">
56
72
  <div class="item">
57
73
  <span class='object_link'><a href="EnvParser.html#parse-class_method" title="EnvParser.parse (method)">parse</a></span>
@@ -95,12 +95,90 @@
95
95
 
96
96
 
97
97
 
98
+
99
+ <h2>
100
+ Instance Method Summary
101
+ <small><a href="#" class="summary_toggle">collapse</a></small>
102
+ </h2>
103
+
104
+ <ul class="summary">
105
+
106
+ <li class="public ">
107
+ <span class="summary_signature">
108
+
109
+ <a href="top-level-namespace.html#filename-instance_method" title="#filename (instance method)">#<strong>filename</strong> &#x21d2; Object </a>
110
+
111
+
112
+
113
+ </span>
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+ <span class="summary_desc"><div class='inline'>
124
+ <p>Load all files listed in “/lib/env_parser/types”.</p>
125
+ </div></span>
126
+
127
+ </li>
128
+
129
+
130
+ </ul>
131
+
132
+
133
+
98
134
 
135
+ <div id="instance_method_details" class="method_details_list">
136
+ <h2>Instance Method Details</h2>
137
+
138
+
139
+ <div class="method_details first">
140
+ <h3 class="signature first" id="filename-instance_method">
141
+
142
+ #<strong>filename</strong> &#x21d2; <tt>Object</tt>
143
+
144
+
145
+
146
+
147
+
148
+ </h3><div class="docstring">
149
+ <div class="discussion">
150
+
151
+ <p>Load all files listed in “/lib/env_parser/types”.</p>
152
+
153
+
154
+ </div>
155
+ </div>
156
+ <div class="tags">
157
+
158
+
159
+ </div><table class="source_code">
160
+ <tr>
161
+ <td>
162
+ <pre class="lines">
163
+
164
+
165
+ 315</pre>
166
+ </td>
167
+ <td>
168
+ <pre class="code"><span class="info file"># File 'lib/env_parser.rb', line 315</span>
169
+
170
+ <span class='const'>Dir</span><span class='period'>.</span><span class='id identifier rubyid_glob'>glob</span><span class='lparen'>(</span><span class='const'>File</span><span class='period'>.</span><span class='id identifier rubyid_join'>join</span><span class='lparen'>(</span><span class='id identifier rubyid___dir__'>__dir__</span><span class='comma'>,</span> <span class='qwords_beg'>%w[</span><span class='tstring_content'>env_parser</span><span class='words_sep'> </span><span class='tstring_content'>types</span><span class='words_sep'> </span><span class='tstring_content'>*.rb</span><span class='words_sep'>]</span><span class='rparen'>)</span><span class='rparen'>)</span><span class='period'>.</span><span class='id identifier rubyid_each'>each</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_filename'>filename</span><span class='op'>|</span> <span class='id identifier rubyid_require_relative'>require_relative</span> <span class='id identifier rubyid_filename'>filename</span> <span class='rbrace'>}</span></pre>
171
+ </td>
172
+ </tr>
173
+ </table>
174
+ </div>
175
+
176
+ </div>
99
177
 
100
178
  </div>
101
179
 
102
180
  <div id="footer">
103
- Generated on Mon Dec 11 23:37:25 2017 by
181
+ Generated on Sun Dec 24 19:33:35 2017 by
104
182
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
183
  0.9.11 (ruby-2.4.2).
106
184
  </div>
@@ -4,12 +4,68 @@ require 'active_support/all'
4
4
  ## The EnvParser class simplifies parsing of environment variables as different data types.
5
5
  ##
6
6
  class EnvParser
7
+ ## Base exception class for EnvParser.
8
+ ##
9
+ class Error < ::StandardError
10
+ end
11
+
7
12
  ## Exception class used to indicate parsed values not allowed per a "from_set" option.
8
13
  ##
9
- class ValueNotAllowed < StandardError
14
+ class ValueNotAllowed < Error
15
+ end
16
+
17
+ ## Exception class used to indicate a type has already been defined.
18
+ ##
19
+ class TypeAlreadyDefined < Error
10
20
  end
11
21
 
12
22
  class << self
23
+ ## Defines a new type for use as the "as" option on a subsequent `.parse` or `.register` call.
24
+ ##
25
+ ## @param name [Symbol]
26
+ ## The name to assign to the type.
27
+ ##
28
+ ## @option options aliases [Array<Symbol>]
29
+ ## An array of additional names you'd like to see refer to this same type.
30
+ ##
31
+ ## @option options if_unset
32
+ ## Specifies a "sensible default" to return for this type if the value being parsed (via
33
+ ## `.parse` or `.register`) is either unset (`nil`) or blank (`''`). Note this may be
34
+ ## overridden by the user via the `.parse`/`.register` "if_unset" option.
35
+ ##
36
+ ## @yield
37
+ ## A block to act as the parser for the this type. If no block is given, an ArgumentError is
38
+ ## raised.
39
+ ##
40
+ ## When the type defined is used via a `.parse`/`.register` call, this block is invoked with
41
+ ## the value to be parsed. Said value is guaranteed to be a non-empty String (the "if_unset"
42
+ ## check will have already run), but no other assurances as to content are given. The block
43
+ ## should return the final output of parsing the given String value as the type being defined.
44
+ ##
45
+ ## If the value given cannot be sensibly parsed into the type defined, the block should raise
46
+ ## an EnvParser::ValueNotAllowed exception.
47
+ ##
48
+ ## @return [nil]
49
+ ## This generates no usable value.
50
+ ##
51
+ ## @raise [ArgumentError, EnvParser::TypeAlreadyDefined]
52
+ ##
53
+ def define_type(name, options = {}, &parser)
54
+ raise(ArgumentError, 'no parsing block given') unless block_given?
55
+
56
+ given_types = (Array(name) + Array(options[:aliases])).map(&:to_s).map(&:to_sym)
57
+ given_types.each do |type|
58
+ raise(TypeAlreadyDefined, "cannot redefine #{type.inspect}") if known_types.key?(type)
59
+
60
+ known_types[type] = {
61
+ parser: parser,
62
+ if_unset: options[:if_unset]
63
+ }
64
+ end
65
+
66
+ nil
67
+ end
68
+
13
69
  ## Interprets the given value as the specified type.
14
70
  ##
15
71
  ## @param value [String, Symbol]
@@ -18,19 +74,10 @@ class EnvParser
18
74
  ##
19
75
  ## @option options as [Symbol]
20
76
  ## The expected return type. A best-effort attempt is made to convert the source String to the
21
- ## requested type. Valid "as" types are:
22
- ##
23
- ## - `:string`
24
- ## - `:symbol`
25
- ## - `:boolean`
26
- ## - `:int` / `:integer`
27
- ## - `:float` / `:decimal` / `:number`
28
- ## - `:json`
29
- ## - `:array`
30
- ## - `:hash`
77
+ ## requested type.
31
78
  ##
32
- ## If no "as" option is given (or the "as" value given is not on the above list), an
33
- ## ArgumentError exception is raised.
79
+ ## If no "as" option is given (or the "as" value given has not been defined), an ArgumentError
80
+ ## exception is raised.
34
81
  ##
35
82
  ## @option options if_unset
36
83
  ## Specifies the default value to return if the given "value" is either unset (`nil`) or blank
@@ -73,20 +120,12 @@ class EnvParser
73
120
  value = ENV[value.to_s] if value.is_a? Symbol
74
121
  value = value.to_s
75
122
 
76
- return options[:if_unset] if value.blank? && options.key?(:if_unset)
123
+ type = known_types[options[:as]]
124
+ raise(ArgumentError, "invalid `as` parameter: #{options[:as].inspect}") unless type
77
125
 
78
- value = case options[:as]
79
- when :string then parse_string(value)
80
- when :symbol then parse_symbol(value)
81
- when :boolean then parse_boolean(value)
82
- when :int, :integer then parse_integer(value)
83
- when :float, :decimal, :number then parse_float(value)
84
- when :json then parse_json(value)
85
- when :array then parse_array(value)
86
- when :hash then parse_hash(value)
87
- else raise ArgumentError, "invalid `as` parameter: #{options[:as].inspect}"
88
- end
126
+ return (options.key?(:if_unset) ? options[:if_unset] : type[:if_unset]) if value.blank?
89
127
 
128
+ value = type[:parser].call(value)
90
129
  check_for_set_inclusion(value, set: options[:from_set]) if options.key?(:from_set)
91
130
  check_user_defined_validations(value, proc: options[:validated_by], block: validation_block)
92
131
 
@@ -203,54 +242,10 @@ class EnvParser
203
242
 
204
243
  private
205
244
 
206
- def parse_string(value)
207
- value
208
- end
209
-
210
- def parse_symbol(value)
211
- value.to_sym
212
- end
213
-
214
- def parse_boolean(value)
215
- case value
216
- when '', '0', 'f', 'false' then false
217
- else true
218
- end
219
- end
220
-
221
- def parse_integer(value)
222
- value.to_i
223
- end
224
-
225
- def parse_float(value)
226
- value.to_f
227
- end
228
-
229
- def parse_json(value)
230
- require 'json'
231
-
232
- return nil if value.blank?
233
-
234
- decoded_json = JSON.parse(value, quirks_mode: true)
235
- { decoded_json: decoded_json }.with_indifferent_access[:decoded_json]
236
- end
237
-
238
- def parse_array(value)
239
- return [] if value.blank?
240
-
241
- decoded_json = parse_json(value)
242
- raise(ArgumentError, 'non-array value') unless decoded_json.is_a? Array
243
-
244
- decoded_json
245
- end
246
-
247
- def parse_hash(value)
248
- return {} if value.blank?
249
-
250
- decoded_json = parse_json(value)
251
- raise(ArgumentError, 'non-hash value') unless decoded_json.is_a? Hash
252
-
253
- decoded_json
245
+ ## Class instance variable for storing known type data.
246
+ ##
247
+ def known_types
248
+ @known_types ||= {}
254
249
  end
255
250
 
256
251
  ## Verifies that the given "value" is included in the "set".
@@ -314,3 +309,7 @@ class EnvParser
314
309
  end
315
310
  end
316
311
  end
312
+
313
+ ## Load all files listed in "/lib/env_parser/types".
314
+ ##
315
+ Dir.glob(File.join(__dir__, %w[env_parser types *.rb])).each { |filename| require_relative filename }
@@ -0,0 +1,39 @@
1
+ require 'env_parser'
2
+
3
+ EnvParser.define_type(:string, if_unset: '') do |value|
4
+ value
5
+ end
6
+
7
+ EnvParser.define_type(:symbol, if_unset: :'', &:to_sym)
8
+
9
+ EnvParser.define_type(:boolean, if_unset: false) do |value|
10
+ case value
11
+ when '', '0', 'f', 'false' then false
12
+ else true
13
+ end
14
+ end
15
+
16
+ EnvParser.define_type(:integer, aliases: %i[int], if_unset: 0, &:to_i)
17
+
18
+ EnvParser.define_type(:float, aliases: %i[decimal number], if_unset: 0.0, &:to_f)
19
+
20
+ EnvParser.define_type(:json, if_unset: nil) do |value|
21
+ require 'json'
22
+
23
+ decoded_json = JSON.parse(value, quirks_mode: true)
24
+ { decoded_json: decoded_json }.with_indifferent_access[:decoded_json]
25
+ end
26
+
27
+ EnvParser.define_type(:array, if_unset: []) do |value|
28
+ decoded_json = EnvParser.parse(value, as: :json)
29
+ raise(ArgumentError, 'non-array value') unless decoded_json.is_a? Array
30
+
31
+ decoded_json
32
+ end
33
+
34
+ EnvParser.define_type(:hash, if_unset: {}) do |value|
35
+ decoded_json = EnvParser.parse(value, as: :json)
36
+ raise(ArgumentError, 'non-hash value') unless decoded_json.is_a? Hash
37
+
38
+ decoded_json
39
+ end
@@ -1,3 +1,3 @@
1
1
  class EnvParser
2
- VERSION = '0.7.0'.freeze
2
+ VERSION = '0.8.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: env_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nestor Custodio
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-12-12 00:00:00.000000000 Z
11
+ date: 2017-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -102,6 +102,8 @@ files:
102
102
  - bin/console
103
103
  - bin/setup
104
104
  - docs/EnvParser.html
105
+ - docs/EnvParser/Error.html
106
+ - docs/EnvParser/TypeAlreadyDefined.html
105
107
  - docs/EnvParser/ValueNotAllowed.html
106
108
  - docs/_index.html
107
109
  - docs/class_list.html
@@ -119,6 +121,7 @@ files:
119
121
  - docs/top-level-namespace.html
120
122
  - env_parser.gemspec
121
123
  - lib/env_parser.rb
124
+ - lib/env_parser/types/base_types.rb
122
125
  - lib/env_parser/version.rb
123
126
  homepage: https://github.com/nestor-custodio/env_parser
124
127
  licenses: