typesafe_config 0.0.3 → 0.0.4
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.
- data/README.md +15 -0
- metadata +3 -40
- data/lib/typesafe/config/config_error.rb +0 -12
- data/lib/typesafe/config/config_factory.rb +0 -9
- data/lib/typesafe/config/config_object.rb +0 -4
- data/lib/typesafe/config/config_parse_options.rb +0 -53
- data/lib/typesafe/config/config_render_options.rb +0 -46
- data/lib/typesafe/config/config_syntax.rb +0 -7
- data/lib/typesafe/config/config_value_type.rb +0 -26
- data/lib/typesafe/config/impl/abstract_config_object.rb +0 -64
- data/lib/typesafe/config/impl/abstract_config_value.rb +0 -130
- data/lib/typesafe/config/impl/config_concatenation.rb +0 -136
- data/lib/typesafe/config/impl/config_float.rb +0 -9
- data/lib/typesafe/config/impl/config_impl.rb +0 -10
- data/lib/typesafe/config/impl/config_impl_util.rb +0 -78
- data/lib/typesafe/config/impl/config_int.rb +0 -31
- data/lib/typesafe/config/impl/config_number.rb +0 -27
- data/lib/typesafe/config/impl/config_string.rb +0 -37
- data/lib/typesafe/config/impl/full_includer.rb +0 -4
- data/lib/typesafe/config/impl/origin_type.rb +0 -9
- data/lib/typesafe/config/impl/parseable.rb +0 -151
- data/lib/typesafe/config/impl/parser.rb +0 -882
- data/lib/typesafe/config/impl/path.rb +0 -59
- data/lib/typesafe/config/impl/path_builder.rb +0 -36
- data/lib/typesafe/config/impl/resolve_status.rb +0 -18
- data/lib/typesafe/config/impl/simple_config.rb +0 -11
- data/lib/typesafe/config/impl/simple_config_list.rb +0 -70
- data/lib/typesafe/config/impl/simple_config_object.rb +0 -178
- data/lib/typesafe/config/impl/simple_config_origin.rb +0 -174
- data/lib/typesafe/config/impl/simple_include_context.rb +0 -7
- data/lib/typesafe/config/impl/simple_includer.rb +0 -19
- data/lib/typesafe/config/impl/token.rb +0 -32
- data/lib/typesafe/config/impl/token_type.rb +0 -42
- data/lib/typesafe/config/impl/tokenizer.rb +0 -370
- data/lib/typesafe/config/impl/tokens.rb +0 -157
- data/lib/typesafe/config/impl/unmergeable.rb +0 -4
- data/lib/typesafe/config/impl.rb +0 -5
- data/lib/typesafe/config.rb +0 -4
- data/lib/typesafe.rb +0 -2
data/README.md
CHANGED
@@ -1,2 +1,17 @@
|
|
1
1
|
ruby-typesafe-config
|
2
2
|
==========
|
3
|
+
|
4
|
+
This is a port of the [Typesafe Config](https://github.com/typesafehub/config) library to Ruby.
|
5
|
+
|
6
|
+
At present, the only features it supports are explicit parsing of config files (.conf/HOCON, .json, .properties) via `ConfigFactory.parse_file`, and rendering a parsed config object back to a String. Testing is minimal and not all data types are supported yet. It also does not yet support `include` or interpolated settings.
|
7
|
+
|
8
|
+
The implementation is intended to be as close to a line-for-line port as the two languages allow, in hopes of making it fairly easy to port over new changesets from the Java code base over time.
|
9
|
+
|
10
|
+
Basic Usage
|
11
|
+
===========
|
12
|
+
|
13
|
+
```rb
|
14
|
+
require 'typesafe/config/config_factory'
|
15
|
+
|
16
|
+
conf = Typesafe::Config::ConfigFactory.parse_file("myapp.conf")
|
17
|
+
conf_map = conf.root.unwrapped
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typesafe_config
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,50 +11,13 @@ bindir: bin
|
|
11
11
|
cert_chain: []
|
12
12
|
date: 2014-03-14 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
|
-
description: ==
|
15
|
-
|
14
|
+
description: == This gem has been replaced by the {HOCON}[https://rubygems.org/gems/ruby_hocon]
|
15
|
+
gem
|
16
16
|
email: chris@puppetlabs.com
|
17
17
|
executables: []
|
18
18
|
extensions: []
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
|
-
- lib/typesafe/config.rb
|
22
|
-
- lib/typesafe/config/config_object.rb
|
23
|
-
- lib/typesafe/config/config_error.rb
|
24
|
-
- lib/typesafe/config/impl/simple_includer.rb
|
25
|
-
- lib/typesafe/config/impl/config_number.rb
|
26
|
-
- lib/typesafe/config/impl/simple_config.rb
|
27
|
-
- lib/typesafe/config/impl/config_int.rb
|
28
|
-
- lib/typesafe/config/impl/resolve_status.rb
|
29
|
-
- lib/typesafe/config/impl/simple_config_origin.rb
|
30
|
-
- lib/typesafe/config/impl/token.rb
|
31
|
-
- lib/typesafe/config/impl/config_string.rb
|
32
|
-
- lib/typesafe/config/impl/config_float.rb
|
33
|
-
- lib/typesafe/config/impl/full_includer.rb
|
34
|
-
- lib/typesafe/config/impl/parser.rb
|
35
|
-
- lib/typesafe/config/impl/tokens.rb
|
36
|
-
- lib/typesafe/config/impl/tokenizer.rb
|
37
|
-
- lib/typesafe/config/impl/abstract_config_object.rb
|
38
|
-
- lib/typesafe/config/impl/simple_include_context.rb
|
39
|
-
- lib/typesafe/config/impl/token_type.rb
|
40
|
-
- lib/typesafe/config/impl/path_builder.rb
|
41
|
-
- lib/typesafe/config/impl/parseable.rb
|
42
|
-
- lib/typesafe/config/impl/path.rb
|
43
|
-
- lib/typesafe/config/impl/unmergeable.rb
|
44
|
-
- lib/typesafe/config/impl/config_impl_util.rb
|
45
|
-
- lib/typesafe/config/impl/simple_config_object.rb
|
46
|
-
- lib/typesafe/config/impl/simple_config_list.rb
|
47
|
-
- lib/typesafe/config/impl/config_impl.rb
|
48
|
-
- lib/typesafe/config/impl/config_concatenation.rb
|
49
|
-
- lib/typesafe/config/impl/abstract_config_value.rb
|
50
|
-
- lib/typesafe/config/impl/origin_type.rb
|
51
|
-
- lib/typesafe/config/config_factory.rb
|
52
|
-
- lib/typesafe/config/impl.rb
|
53
|
-
- lib/typesafe/config/config_parse_options.rb
|
54
|
-
- lib/typesafe/config/config_render_options.rb
|
55
|
-
- lib/typesafe/config/config_value_type.rb
|
56
|
-
- lib/typesafe/config/config_syntax.rb
|
57
|
-
- lib/typesafe.rb
|
58
21
|
- LICENSE
|
59
22
|
- README.md
|
60
23
|
homepage: https://github.com/cprice404/ruby-typesafe-config
|
@@ -1,9 +0,0 @@
|
|
1
|
-
require 'typesafe/config'
|
2
|
-
require 'typesafe/config/config_parse_options'
|
3
|
-
require 'typesafe/config/impl/parseable'
|
4
|
-
|
5
|
-
class Typesafe::Config::ConfigFactory
|
6
|
-
def self.parse_file(file_path, options = Typesafe::Config::ConfigParseOptions.defaults)
|
7
|
-
Typesafe::Config::Impl::Parseable.new_file(file_path, options).parse.to_config
|
8
|
-
end
|
9
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
require 'typesafe/config'
|
2
|
-
|
3
|
-
class Typesafe::Config::ConfigParseOptions
|
4
|
-
attr_accessor :syntax, :origin_description, :allow_missing, :includer
|
5
|
-
|
6
|
-
def self.defaults
|
7
|
-
self.new(nil, nil, true, nil)
|
8
|
-
end
|
9
|
-
|
10
|
-
def initialize(syntax, origin_description, allow_missing, includer)
|
11
|
-
@syntax = syntax
|
12
|
-
@origin_description = origin_description
|
13
|
-
@allow_missing = allow_missing
|
14
|
-
@includer = includer
|
15
|
-
end
|
16
|
-
|
17
|
-
def allow_missing?
|
18
|
-
@allow_missing
|
19
|
-
end
|
20
|
-
|
21
|
-
def with_syntax(syntax)
|
22
|
-
if @syntax == syntax
|
23
|
-
self
|
24
|
-
else
|
25
|
-
Typesafe::Config::ConfigParseOptions.new(syntax,
|
26
|
-
@origin_description,
|
27
|
-
@allow_missing,
|
28
|
-
@includer)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def with_includer(includer)
|
33
|
-
if @includer == includer
|
34
|
-
self
|
35
|
-
else
|
36
|
-
Typesafe::Config::ConfigParseOptions.new(@syntax,
|
37
|
-
@origin_description,
|
38
|
-
@allow_missing,
|
39
|
-
includer)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def append_includer(includer)
|
44
|
-
if @includer == includer
|
45
|
-
self
|
46
|
-
elsif @includer
|
47
|
-
with_includer(@includer.with_fallback(includer))
|
48
|
-
else
|
49
|
-
with_includer(includer)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'typesafe/config'
|
2
|
-
|
3
|
-
class Typesafe::Config::ConfigRenderOptions
|
4
|
-
def initialize(origin_comments, comments, formatted, json)
|
5
|
-
@origin_comments = origin_comments
|
6
|
-
@comments = comments
|
7
|
-
@formatted = formatted
|
8
|
-
@json = json
|
9
|
-
end
|
10
|
-
|
11
|
-
attr_writer :origin_comments, :comments, :formatted, :json
|
12
|
-
|
13
|
-
def origin_comments?
|
14
|
-
@origin_comments
|
15
|
-
end
|
16
|
-
def comments?
|
17
|
-
@comments
|
18
|
-
end
|
19
|
-
def formatted?
|
20
|
-
@formatted
|
21
|
-
end
|
22
|
-
def json?
|
23
|
-
@json
|
24
|
-
end
|
25
|
-
|
26
|
-
#
|
27
|
-
# Returns the default render options which are verbose (commented and
|
28
|
-
# formatted). See {@link ConfigRenderOptions#concise} for stripped-down
|
29
|
-
# options. This rendering will not be valid JSON since it has comments.
|
30
|
-
#
|
31
|
-
# @return the default render options
|
32
|
-
#
|
33
|
-
def self.defaults
|
34
|
-
Typesafe::Config::ConfigRenderOptions.new(true, true, true, true)
|
35
|
-
end
|
36
|
-
|
37
|
-
#
|
38
|
-
# Returns concise render options (no whitespace or comments). For a
|
39
|
-
# resolved {@link Config}, the concise rendering will be valid JSON.
|
40
|
-
#
|
41
|
-
# @return the concise render options
|
42
|
-
#
|
43
|
-
def self.concise
|
44
|
-
Typesafe::Config::ConfigRenderOptions.new(false, false, false, true)
|
45
|
-
end
|
46
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'typesafe/config'
|
2
|
-
|
3
|
-
#
|
4
|
-
# The type of a configuration value (following the <a
|
5
|
-
# href="http://json.org">JSON</a> type schema).
|
6
|
-
#
|
7
|
-
module Typesafe::Config::ConfigValueType
|
8
|
-
OBJECT = 0
|
9
|
-
LIST = 1
|
10
|
-
NUMBER = 2
|
11
|
-
BOOLEAN = 3
|
12
|
-
NULL = 4
|
13
|
-
STRING = 5
|
14
|
-
|
15
|
-
def self.name(config_value_type)
|
16
|
-
case config_value_type
|
17
|
-
when OBJECT then "OBJECT"
|
18
|
-
when LIST then "LIST"
|
19
|
-
when NUMBER then "NUMBER"
|
20
|
-
when BOOLEAN then "BOOLEAN"
|
21
|
-
when NULL then "NULL"
|
22
|
-
when STRING then "STRING"
|
23
|
-
else raise ConfigBugError, "Unrecognized value type '#{config_value_type}'"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'typesafe/config/impl'
|
2
|
-
require 'typesafe/config/impl/abstract_config_value'
|
3
|
-
require 'typesafe/config/impl/simple_config'
|
4
|
-
require 'typesafe/config/config_object'
|
5
|
-
require 'typesafe/config/config_value_type'
|
6
|
-
require 'typesafe/config/impl/resolve_status'
|
7
|
-
require 'typesafe/config/impl/simple_config_origin'
|
8
|
-
|
9
|
-
class Typesafe::Config::Impl::AbstractConfigObject < Typesafe::Config::Impl::AbstractConfigValue
|
10
|
-
include Typesafe::Config::ConfigObject
|
11
|
-
|
12
|
-
def initialize(origin)
|
13
|
-
super(origin)
|
14
|
-
@config = Typesafe::Config::Impl::SimpleConfig.new(self)
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_config
|
18
|
-
@config
|
19
|
-
end
|
20
|
-
|
21
|
-
def to_fallback_value
|
22
|
-
self
|
23
|
-
end
|
24
|
-
|
25
|
-
def value_type
|
26
|
-
Typesafe::Config::ConfigValueType::OBJECT
|
27
|
-
end
|
28
|
-
|
29
|
-
def new_copy(origin)
|
30
|
-
new_copy_with_status(resolve_status, origin)
|
31
|
-
end
|
32
|
-
|
33
|
-
def merge_origins(stack)
|
34
|
-
if stack.empty?
|
35
|
-
raise ConfigBugError, "can't merge origins on empty list"
|
36
|
-
end
|
37
|
-
origins = []
|
38
|
-
first_origin = nil
|
39
|
-
num_merged = 0
|
40
|
-
stack.each do |v|
|
41
|
-
if first_origin.nil?
|
42
|
-
first_origin = v.origin
|
43
|
-
end
|
44
|
-
|
45
|
-
if (v.is_a?(Typesafe::Config::Impl::AbstractConfigObject)) &&
|
46
|
-
(v.resolve_status == Typesafe::Config::Impl::ResolveStatus::RESOLVED) &&
|
47
|
-
v.empty?
|
48
|
-
# don't include empty files or the .empty()
|
49
|
-
# config in the description, since they are
|
50
|
-
# likely to be "implementation details"
|
51
|
-
else
|
52
|
-
origins.push(v.origin)
|
53
|
-
num_merged += 1
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
if num_merged == 0
|
58
|
-
# the configs were all empty, so just use the first one
|
59
|
-
origins.push(first_origin)
|
60
|
-
end
|
61
|
-
|
62
|
-
Typesafe::Config::Impl::SimpleConfigOrigin.merge_origins(origins)
|
63
|
-
end
|
64
|
-
end
|
@@ -1,130 +0,0 @@
|
|
1
|
-
require 'typesafe/config/impl'
|
2
|
-
require 'stringio'
|
3
|
-
require 'typesafe/config/config_render_options'
|
4
|
-
require 'typesafe/config/config_object'
|
5
|
-
require 'typesafe/config/impl/resolve_status'
|
6
|
-
require 'typesafe/config/impl/unmergeable'
|
7
|
-
require 'typesafe/config/impl/abstract_config_object'
|
8
|
-
require 'typesafe/config/impl/config_impl_util'
|
9
|
-
|
10
|
-
##
|
11
|
-
## Trying very hard to avoid a parent reference in config values; when you have
|
12
|
-
## a tree like this, the availability of parent() tends to result in a lot of
|
13
|
-
## improperly-factored and non-modular code. Please don't add parent().
|
14
|
-
##
|
15
|
-
class Typesafe::Config::Impl::AbstractConfigValue
|
16
|
-
ConfigImplUtil = Typesafe::Config::Impl::ConfigImplUtil
|
17
|
-
|
18
|
-
def initialize(origin)
|
19
|
-
@origin = origin
|
20
|
-
end
|
21
|
-
|
22
|
-
attr_reader :origin
|
23
|
-
|
24
|
-
def resolve_status
|
25
|
-
Typesafe::Config::Impl::ResolveStatus::RESOLVED
|
26
|
-
end
|
27
|
-
|
28
|
-
# this is virtualized rather than a field because only some subclasses
|
29
|
-
# really need to store the boolean, and they may be able to pack it
|
30
|
-
# with another boolean to save space.
|
31
|
-
def ignores_fallbacks?
|
32
|
-
# if we are not resolved, then somewhere in this value there's
|
33
|
-
# a substitution that may need to look at the fallbacks.
|
34
|
-
resolve_status == Typesafe::Config::Impl::ResolveStatus::RESOLVED
|
35
|
-
end
|
36
|
-
|
37
|
-
# the withFallback() implementation is supposed to avoid calling
|
38
|
-
# mergedWith* if we're ignoring fallbacks.
|
39
|
-
def require_not_ignoring_fallbacks
|
40
|
-
if ignores_fallbacks?
|
41
|
-
raise ConfigBugError, "method should not have been called with ignoresFallbacks=true #{self.class.name}"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def with_origin(origin)
|
46
|
-
if @origin == origin
|
47
|
-
self
|
48
|
-
else
|
49
|
-
new_copy(origin)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def with_fallback(mergeable)
|
54
|
-
if ignores_fallbacks?
|
55
|
-
self
|
56
|
-
else
|
57
|
-
other = mergeable.to_fallback_value
|
58
|
-
if other.is_a?(Typesafe::Config::Impl::Unmergeable)
|
59
|
-
merged_with_the_unmergeable(other)
|
60
|
-
elsif other.is_a?(Typesafe::Config::Impl::AbstractConfigObject)
|
61
|
-
merged_with_object(other)
|
62
|
-
else
|
63
|
-
merged_with_non_object(other)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def to_s
|
69
|
-
sb = StringIO.new
|
70
|
-
render_to_sb(sb, 0, true, nil, Typesafe::Config::ConfigRenderOptions.concise)
|
71
|
-
"#{self.class.name}(#{sb.string})"
|
72
|
-
end
|
73
|
-
|
74
|
-
def indent(sb, indent_size, options)
|
75
|
-
if options.formatted?
|
76
|
-
remaining = indent_size
|
77
|
-
while remaining > 0
|
78
|
-
sb << " "
|
79
|
-
remaining -= 1
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def render_to_sb(sb, indent, at_root, at_key, options)
|
85
|
-
if !at_key.nil?
|
86
|
-
rendered_key =
|
87
|
-
if options.json?
|
88
|
-
ConfigImplUtil.render_json_string(at_key)
|
89
|
-
else
|
90
|
-
ConfigImplUtil.render_string_unquoted_if_possible(at_key)
|
91
|
-
end
|
92
|
-
|
93
|
-
sb << rendered_key
|
94
|
-
|
95
|
-
if options.json?
|
96
|
-
if options.formatted?
|
97
|
-
sb << " : "
|
98
|
-
else
|
99
|
-
sb << ":"
|
100
|
-
end
|
101
|
-
else
|
102
|
-
# in non-JSON we can omit the colon or equals before an object
|
103
|
-
if self.is_a?(Typesafe::Config::ConfigObject)
|
104
|
-
if options.formatted?
|
105
|
-
sb << ' '
|
106
|
-
end
|
107
|
-
else
|
108
|
-
sb << "="
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
render_value_to_sb(sb, indent, at_root, options)
|
113
|
-
end
|
114
|
-
|
115
|
-
# to be overridden by subclasses
|
116
|
-
def render_value_to_sb(sb, indent, at_root, options)
|
117
|
-
u = unwrapped
|
118
|
-
sb << u.to_s
|
119
|
-
end
|
120
|
-
|
121
|
-
def render(options = Typesafe::Config::ConfigRenderOptions.defaults)
|
122
|
-
sb = StringIO.new
|
123
|
-
render_to_sb(sb, 0, true, nil, options)
|
124
|
-
# We take a substring that ends at sb.pos, because we've been decrementing
|
125
|
-
# sb.pos at various points in the code as a means to remove characters from
|
126
|
-
# the end of the StringIO
|
127
|
-
sb.string[0, sb.pos]
|
128
|
-
end
|
129
|
-
|
130
|
-
end
|
@@ -1,136 +0,0 @@
|
|
1
|
-
require 'typesafe/config/impl'
|
2
|
-
require 'typesafe/config/impl/abstract_config_value'
|
3
|
-
require 'typesafe/config/impl/abstract_config_object'
|
4
|
-
require 'typesafe/config/impl/simple_config_list'
|
5
|
-
require 'typesafe/config/config_object'
|
6
|
-
require 'typesafe/config/impl/unmergeable'
|
7
|
-
require 'typesafe/config/impl/simple_config_origin'
|
8
|
-
require 'typesafe/config/impl/config_string'
|
9
|
-
|
10
|
-
class Typesafe::Config::Impl::ConfigConcatenation < Typesafe::Config::Impl::AbstractConfigValue
|
11
|
-
include Typesafe::Config::Impl::Unmergeable
|
12
|
-
|
13
|
-
SimpleConfigList = Typesafe::Config::Impl::SimpleConfigList
|
14
|
-
ConfigObject = Typesafe::Config::ConfigObject
|
15
|
-
Unmergeable = Typesafe::Config::Impl::Unmergeable
|
16
|
-
SimpleConfigOrigin = Typesafe::Config::Impl::SimpleConfigOrigin
|
17
|
-
|
18
|
-
#
|
19
|
-
# Add left and right, or their merger, to builder
|
20
|
-
#
|
21
|
-
def self.join(builder, orig_right)
|
22
|
-
left = builder[builder.size - 1]
|
23
|
-
right = orig_right
|
24
|
-
|
25
|
-
# check for an object which can be converted to a list
|
26
|
-
# (this will be an object with numeric keys, like foo.0, foo.1)
|
27
|
-
if (left.is_a?(ConfigObject)) && (right.is_a?(SimpleConfigList))
|
28
|
-
left = DefaultTransformer.transform(left, ConfigValueType::LIST)
|
29
|
-
elsif (left.is_a?(SimpleConfigList)) && (right.is_a?(ConfigObject))
|
30
|
-
right = DefaultTransformer.transform(right, ConfigValueType::LIST)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Since this depends on the type of two instances, I couldn't think
|
34
|
-
# of much alternative to an instanceof chain. Visitors are sometimes
|
35
|
-
# used for multiple dispatch but seems like overkill.
|
36
|
-
joined = nil
|
37
|
-
if (left.is_a?(ConfigObject)) && (right.is_a?(ConfigObject))
|
38
|
-
joined = right.with_fallback(left)
|
39
|
-
elsif (left.is_a?(SimpleConfigList)) && (right.is_a?(SimpleConfigList))
|
40
|
-
joined = left.concatenate(right)
|
41
|
-
elsif (left.is_a?(Typesafe::Config::Impl::ConfigConcatenation)) ||
|
42
|
-
(right.is_a?(Typesafe::Config::Impl::ConfigConcatenation))
|
43
|
-
raise ConfigBugError, "unflattened ConfigConcatenation"
|
44
|
-
elsif (left.is_a?(Unmergeable)) || (right.is_a?(Unmergeable))
|
45
|
-
# leave joined=null, cannot join
|
46
|
-
else
|
47
|
-
# handle primitive type or primitive type mixed with object or list
|
48
|
-
s1 = left.transform_to_string
|
49
|
-
s2 = right.transform_to_string
|
50
|
-
if s1.nil? || s2.nil?
|
51
|
-
raise ConfigWrongTypeError.new(left.origin,
|
52
|
-
"Cannot concatenate object or list with a non-object-or-list, #{left} " +
|
53
|
-
"and #{right} are not compatible")
|
54
|
-
else
|
55
|
-
joined_origin = SimpleConfigOrigin.merge_origins([left.origin, right.origin])
|
56
|
-
joined = Typesafe::Config::Impl::ConfigString.new(joined_origin, s1 + s2)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
if joined.nil?
|
61
|
-
builder.push(right)
|
62
|
-
else
|
63
|
-
builder.pop
|
64
|
-
builder.push(joined)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.consolidate(pieces)
|
69
|
-
if pieces.length < 2
|
70
|
-
pieces
|
71
|
-
else
|
72
|
-
flattened = []
|
73
|
-
pieces.each do |v|
|
74
|
-
if v.is_a?(Typesafe::Config::Impl::ConfigConcatenation)
|
75
|
-
flattened.concat(v.pieces)
|
76
|
-
else
|
77
|
-
flattened.push(v)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
consolidated = []
|
82
|
-
flattened.each do |v|
|
83
|
-
if consolidated.empty?
|
84
|
-
consolidated.push(v)
|
85
|
-
else
|
86
|
-
join(consolidated, v)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
consolidated
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def self.concatenate(pieces)
|
95
|
-
consolidated = consolidate(pieces)
|
96
|
-
if consolidated.empty?
|
97
|
-
nil
|
98
|
-
elsif consolidated.length == 1
|
99
|
-
consolidated[0]
|
100
|
-
else
|
101
|
-
merged_origin = SimpleConfigOrigin.merge_origins(consolidated)
|
102
|
-
Typesafe::Config::Impl::ConfigConcatenation.new(merged_origin, consolidated)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
|
107
|
-
def initialize(origin, pieces)
|
108
|
-
super(origin)
|
109
|
-
@pieces = pieces
|
110
|
-
|
111
|
-
if pieces.size < 2
|
112
|
-
raise ConfigBugError, "Created concatenation with less than 2 items: #{self}"
|
113
|
-
end
|
114
|
-
|
115
|
-
had_unmergeable = false
|
116
|
-
pieces.each do |p|
|
117
|
-
if p.is_a?(Typesafe::Config::Impl::ConfigConcatenation)
|
118
|
-
raise ConfigBugError, "ConfigConcatenation should never be nested: #{self}"
|
119
|
-
end
|
120
|
-
if p.is_a?(Unmergeable)
|
121
|
-
had_unmergeable = true
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
unless had_unmergeable
|
126
|
-
raise ConfigBugError, "Created concatenation without an unmergeable in it: #{self}"
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def ignores_fallbacks?
|
131
|
-
# we can never ignore fallbacks because if a child ConfigReference
|
132
|
-
# is self-referential we have to look lower in the merge stack
|
133
|
-
# for its value.
|
134
|
-
false
|
135
|
-
end
|
136
|
-
end
|
@@ -1,9 +0,0 @@
|
|
1
|
-
require 'typesafe/config/impl'
|
2
|
-
require 'typesafe/config/impl/config_number'
|
3
|
-
|
4
|
-
class Typesafe::Config::Impl::ConfigFloat < Typesafe::Config::Impl::ConfigNumber
|
5
|
-
def initialize(origin, value, original_text)
|
6
|
-
super(origin, original_text)
|
7
|
-
@value = value
|
8
|
-
end
|
9
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
require 'typesafe/config/impl'
|
2
|
-
require 'stringio'
|
3
|
-
|
4
|
-
class Typesafe::Config::Impl::ConfigImplUtil
|
5
|
-
def self.equals_handling_nil?(a, b)
|
6
|
-
# This method probably doesn't make any sense in ruby... not sure
|
7
|
-
if a.nil? && !b.nil?
|
8
|
-
false
|
9
|
-
elsif !a.nil? && b.nil?
|
10
|
-
false
|
11
|
-
# in ruby, the == and .equal? are the opposite of what they are in Java
|
12
|
-
elsif a.equal?(b)
|
13
|
-
true
|
14
|
-
else
|
15
|
-
a == b
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
#
|
20
|
-
# This is public ONLY for use by the "config" package, DO NOT USE this ABI
|
21
|
-
# may change.
|
22
|
-
#
|
23
|
-
def self.render_json_string(s)
|
24
|
-
sb = StringIO.new
|
25
|
-
sb << '"'
|
26
|
-
s.chars.each do |c|
|
27
|
-
case c
|
28
|
-
when '"' then sb << "\\\""
|
29
|
-
when "\\" then sb << "\\\\"
|
30
|
-
when "\n" then sb << "\\n"
|
31
|
-
when "\b" then sb << "\\b"
|
32
|
-
when "\f" then sb << "\\f"
|
33
|
-
when "\r" then sb << "\\r"
|
34
|
-
when "\t" then sb << "\\t"
|
35
|
-
else
|
36
|
-
if c =~ /[[:cntrl:]]/
|
37
|
-
sb << ("\\u%04x" % c)
|
38
|
-
else
|
39
|
-
sb << c
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
sb << '"'
|
44
|
-
sb.string
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.render_string_unquoted_if_possible(s)
|
48
|
-
# this can quote unnecessarily as long as it never fails to quote when
|
49
|
-
# necessary
|
50
|
-
if s.length == 0
|
51
|
-
return render_json_string(s)
|
52
|
-
end
|
53
|
-
|
54
|
-
# if it starts with a hyphen or number, we have to quote
|
55
|
-
# to ensure we end up with a string and not a number
|
56
|
-
first = s.chars.first
|
57
|
-
if (first =~ /[[:digit:]]/) || (first == '-')
|
58
|
-
return render_json_string(s)
|
59
|
-
end
|
60
|
-
|
61
|
-
# only unquote if it's pure alphanumeric
|
62
|
-
s.chars.each do |c|
|
63
|
-
unless (c =~ /[[:alnum:]]/) || (c == '-')
|
64
|
-
return render_json_string(s)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
s
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.whitespace?(c)
|
72
|
-
# this implementation is *not* a port of the java code, because it relied on
|
73
|
-
# the method java.lang.Character#isWhitespace. This is probably
|
74
|
-
# insanely slow (running a regex against every single character in the
|
75
|
-
# file).
|
76
|
-
c =~ /[[:space:]]/
|
77
|
-
end
|
78
|
-
end
|