kdl 1.0.5 → 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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +7 -1
  3. data/.gitignore +1 -0
  4. data/.gitmodules +4 -0
  5. data/Gemfile +6 -1
  6. data/README.md +51 -7
  7. data/Rakefile +6 -1
  8. data/bin/kdl +1 -1
  9. data/kdl.gemspec +2 -2
  10. data/lib/kdl/document.rb +58 -2
  11. data/lib/kdl/kdl.tab.rb +303 -228
  12. data/lib/kdl/kdl.yy +57 -49
  13. data/lib/kdl/node.rb +113 -12
  14. data/lib/kdl/parser_common.rb +26 -0
  15. data/lib/kdl/string_dumper.rb +30 -33
  16. data/lib/kdl/tokenizer.rb +350 -113
  17. data/lib/kdl/types/base64.rb +1 -1
  18. data/lib/kdl/types/country/iso3166_countries.rb +1 -1
  19. data/lib/kdl/types/country/iso3166_subdivisions.rb +1 -1
  20. data/lib/kdl/types/country.rb +2 -2
  21. data/lib/kdl/types/currency/iso4217_currencies.rb +1 -1
  22. data/lib/kdl/types/currency.rb +1 -1
  23. data/lib/kdl/types/date_time.rb +3 -3
  24. data/lib/kdl/types/decimal.rb +1 -1
  25. data/lib/kdl/types/duration/iso8601_parser.rb +1 -1
  26. data/lib/kdl/types/duration.rb +1 -1
  27. data/lib/kdl/types/email/parser.rb +2 -2
  28. data/lib/kdl/types/email.rb +1 -1
  29. data/lib/kdl/types/hostname/validator.rb +1 -1
  30. data/lib/kdl/types/hostname.rb +1 -1
  31. data/lib/kdl/types/ip.rb +1 -1
  32. data/lib/kdl/types/irl/parser.rb +1 -1
  33. data/lib/kdl/types/irl.rb +1 -1
  34. data/lib/kdl/types/regex.rb +1 -1
  35. data/lib/kdl/types/url.rb +1 -1
  36. data/lib/kdl/types/url_template.rb +1 -1
  37. data/lib/kdl/types/uuid.rb +1 -1
  38. data/lib/kdl/v1/document.rb +17 -0
  39. data/lib/kdl/v1/kdl.tab.rb +594 -0
  40. data/lib/kdl/v1/kdl.yy +89 -0
  41. data/lib/kdl/v1/node.rb +30 -0
  42. data/lib/kdl/v1/string_dumper.rb +28 -0
  43. data/lib/kdl/v1/tokenizer.rb +296 -0
  44. data/lib/kdl/v1/value.rb +89 -0
  45. data/lib/kdl/v1.rb +11 -0
  46. data/lib/kdl/value.rb +81 -12
  47. data/lib/kdl/version.rb +1 -1
  48. data/lib/kdl.rb +40 -1
  49. metadata +13 -4
@@ -0,0 +1,28 @@
1
+ module KDL
2
+ module V1
3
+ module StringDumper
4
+ include ::KDL::StringDumper
5
+
6
+ def call(string)
7
+ %("#{string.each_char.map { |char| escape(char) }.join}")
8
+ end
9
+
10
+ def stringify_identifier(ident)
11
+ if bare_identifier?(ident)
12
+ ident
13
+ else
14
+ call(ident)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def bare_identifier?(name)
21
+ escape_chars = '\\\/(){}<>;\[\]=,"'
22
+ name =~ /^([^0-9\-+\s#{escape_chars}][^\s#{escape_chars}]*|[\-+](?!true|false|null)[^0-9\s#{escape_chars}][^\s#{escape_chars}]*)$/
23
+ end
24
+
25
+ extend self
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,296 @@
1
+ module KDL
2
+ module V1
3
+ class Tokenizer < KDL::Tokenizer
4
+ NON_IDENTIFIER_CHARS = Regexp.escape "#{SYMBOLS.keys.join}()/\\<>[]\",#{WHITESPACE.join}#{OTHER_NON_IDENTIFIER_CHARS.join}"
5
+ IDENTIFIER_CHARS = /[^#{NON_IDENTIFIER_CHARS}]/
6
+ INITIAL_IDENTIFIER_CHARS = /[^#{NON_IDENTIFIER_CHARS}0-9]/
7
+
8
+ def next_token
9
+ @context = nil
10
+ @previous_context = nil
11
+ @line_at_start = @line
12
+ @column_at_start = @column
13
+ loop do
14
+ c = self[@index]
15
+ case @context
16
+ when nil
17
+ case c
18
+ when '"'
19
+ self.context = :string
20
+ @buffer = ''
21
+ traverse(1)
22
+ when 'r'
23
+ if @str[@index + 1] == '"'
24
+ self.context = :rawstring
25
+ traverse(2)
26
+ @rawstring_hashes = 0
27
+ @buffer = ''
28
+ next
29
+ elsif @str[@index + 1] == '#'
30
+ i = @index + 1
31
+ @rawstring_hashes = 0
32
+ while @str[i] == '#'
33
+ @rawstring_hashes += 1
34
+ i += 1
35
+ end
36
+ if @str[i] == '"'
37
+ self.context = :rawstring
38
+ @index = i + 1
39
+ @buffer = ''
40
+ next
41
+ end
42
+ end
43
+ self.context = :ident
44
+ @buffer = c
45
+ traverse(1)
46
+ when '-'
47
+ n = self[@index + 1]
48
+ if n =~ /[0-9]/
49
+ n2 = self[@index + 2]
50
+ if n == '0' && n2 =~ /[box]/
51
+ self.context = integer_context(n2)
52
+ traverse(3)
53
+ else
54
+ self.context = :decimal
55
+ traverse(1)
56
+ end
57
+ else
58
+ self.context = :ident
59
+ traverse(1)
60
+ end
61
+ @buffer = c
62
+ when /[0-9+]/
63
+ n = self[@index + 1]
64
+ if c == '0' && n =~ /[box]/
65
+ traverse(2)
66
+ @buffer = ''
67
+ self.context = integer_context(n)
68
+ else
69
+ self.context = :decimal
70
+ @buffer = c
71
+ traverse(1)
72
+ end
73
+ when '\\'
74
+ t = Tokenizer.new(@str, @index + 1)
75
+ la = t.next_token
76
+ if la[0] == :NEWLINE || la[0] == :EOF || (la[0] == :WS && (lan = t.next_token[0]) == :NEWLINE || lan == :EOF)
77
+ traverse_to(t.index)
78
+ @buffer = "#{c}#{la[1].value}"
79
+ @buffer += "\n" if lan == :NEWLINE
80
+ self.context = :whitespace
81
+ else
82
+ raise_error "Unexpected '\\' (#{la[0]})"
83
+ end
84
+ when *SYMBOLS.keys
85
+ return token(SYMBOLS[c], c).tap { traverse(1) }
86
+ when *NEWLINES, "\r"
87
+ nl = expect_newline
88
+ return token(:NEWLINE, nl).tap do
89
+ traverse(nl.length)
90
+ end
91
+ when "/"
92
+ if self[@index + 1] == '/'
93
+ self.context = :single_line_comment
94
+ traverse(2)
95
+ elsif self[@index + 1] == '*'
96
+ self.context = :multi_line_comment
97
+ @comment_nesting = 1
98
+ traverse(2)
99
+ elsif self[@index + 1] == '-'
100
+ return token(:SLASHDASH, '/-').tap { traverse(2) }
101
+ else
102
+ self.context = :ident
103
+ @buffer = c
104
+ traverse(1)
105
+ end
106
+ when *WHITESPACE
107
+ self.context = :whitespace
108
+ @buffer = c
109
+ traverse(1)
110
+ when nil
111
+ return [false, token(:EOF, :EOF)[1]] if @done
112
+
113
+ @done = true
114
+ return token(:EOF, :EOF)
115
+ when INITIAL_IDENTIFIER_CHARS
116
+ self.context = :ident
117
+ @buffer = c
118
+ traverse(1)
119
+ when '('
120
+ @type_context = true
121
+ return token(:LPAREN, c).tap { traverse(1) }
122
+ when ')'
123
+ @type_context = false
124
+ return token(:RPAREN, c).tap { traverse(1) }
125
+ else
126
+ raise_error "Unexpected character #{c.inspect}"
127
+ end
128
+ when :ident
129
+ case c
130
+ when IDENTIFIER_CHARS
131
+ traverse(1)
132
+ @buffer += c
133
+ else
134
+ case @buffer
135
+ when 'true' then return token(:TRUE, true)
136
+ when 'false' then return token(:FALSE, false)
137
+ when 'null' then return token(:NULL, nil)
138
+ else return token(:IDENT, @buffer)
139
+ end
140
+ end
141
+ when :string
142
+ case c
143
+ when '\\'
144
+ c2 = self[@index + 1]
145
+ if c2.match?(NEWLINES_PATTERN)
146
+ i = 2
147
+ while self[@index + i].match?(NEWLINES_PATTERN)
148
+ i+=1
149
+ end
150
+ traverse(i)
151
+ else
152
+ @buffer += c
153
+ @buffer += c2
154
+ traverse(2)
155
+ end
156
+ when '"'
157
+ return token(:STRING, unescape(@buffer)).tap { traverse(1) }
158
+ when nil
159
+ raise_error "Unterminated string literal"
160
+ else
161
+ @buffer += c
162
+ traverse(1)
163
+ end
164
+ when :rawstring
165
+ raise_error "Unterminated rawstring literal" if c.nil?
166
+
167
+ if c == '"'
168
+ h = 0
169
+ h += 1 while self[@index + 1 + h] == '#' && h < @rawstring_hashes
170
+ if h == @rawstring_hashes
171
+ return token(:RAWSTRING, @buffer).tap { traverse(1 + h) }
172
+ end
173
+ end
174
+
175
+ @buffer += c
176
+ traverse(1)
177
+ when :decimal
178
+ case c
179
+ when /[0-9.\-+_eE]/
180
+ traverse(1)
181
+ @buffer += c
182
+ else
183
+ return parse_decimal(@buffer)
184
+ end
185
+ when :hexadecimal
186
+ case c
187
+ when /[0-9a-fA-F_]/
188
+ traverse(1)
189
+ @buffer += c
190
+ else
191
+ return parse_hexadecimal(@buffer)
192
+ end
193
+ when :octal
194
+ case c
195
+ when /[0-7_]/
196
+ traverse(1)
197
+ @buffer += c
198
+ else
199
+ return parse_octal(@buffer)
200
+ end
201
+ when :binary
202
+ case c
203
+ when /[01_]/
204
+ traverse(1)
205
+ @buffer += c
206
+ else
207
+ return parse_binary(@buffer)
208
+ end
209
+ when :single_line_comment
210
+ case c
211
+ when *NEWLINES, "\r"
212
+ self.context = nil
213
+ @column_at_start = @column
214
+ next
215
+ when nil
216
+ @done = true
217
+ return token(:EOF, :EOF)
218
+ else
219
+ traverse(1)
220
+ end
221
+ when :multi_line_comment
222
+ if c == '/' && self[@index + 1] == '*'
223
+ @comment_nesting += 1
224
+ traverse(2)
225
+ elsif c == '*' && self[@index + 1] == '/'
226
+ @comment_nesting -= 1
227
+ traverse(2)
228
+ if @comment_nesting == 0
229
+ revert_context
230
+ end
231
+ else
232
+ traverse(1)
233
+ end
234
+ when :whitespace
235
+ if WHITESPACE.include?(c)
236
+ traverse(1)
237
+ @buffer += c
238
+ elsif c == "/" && self[@index + 1] == '*'
239
+ self.context = :multi_line_comment
240
+ @comment_nesting = 1
241
+ traverse(2)
242
+ elsif c == "\\"
243
+ t = Tokenizer.new(@str, @index + 1)
244
+ la = t.next_token
245
+ if la[0] == :NEWLINE || la[0] == :EOF || (la[0] == :WS && (lan = t.next_token[0]) == :NEWLINE || lan == :EOF)
246
+ traverse_to(t.index)
247
+ @buffer += "#{c}#{la[1].value}"
248
+ @buffer += "\n" if lan == :NEWLINE
249
+ else
250
+ raise_error "Unexpected '\\' (#{la[0]})"
251
+ end
252
+ else
253
+ return token(:WS, @buffer)
254
+ end
255
+ else
256
+ # :nocov:
257
+ raise_error "Unknown context `#{@context}'"
258
+ # :nocov:
259
+ end
260
+ end
261
+ end
262
+
263
+ private
264
+
265
+ def allowed_in_type?(val)
266
+ %i[ident string rawstring].include?(val)
267
+ end
268
+
269
+ def allowed_after_type?(val)
270
+ !%i[single_line_comment multi_line_comment].include?(val)
271
+ end
272
+
273
+ def unescape(string)
274
+ string.gsub(/\\[^u]/) do |m|
275
+ case m
276
+ when '\n' then "\n"
277
+ when '\r' then "\r"
278
+ when '\t' then "\t"
279
+ when '\\\\' then "\\"
280
+ when '\"' then "\""
281
+ when '\b' then "\b"
282
+ when '\f' then "\f"
283
+ when '\/' then "/"
284
+ else raise_error "Unexpected escape #{m.inspect}"
285
+ end
286
+ end.gsub(/\\u\{[0-9a-fA-F]{0,6}\}/) do |m|
287
+ i = Integer(m[3..-2], 16)
288
+ if i < 0 || i > 0x10FFFF
289
+ raise_error "Invalid code point #{u}"
290
+ end
291
+ i.chr(Encoding::UTF_8)
292
+ end
293
+ end
294
+ end
295
+ end
296
+ end
@@ -0,0 +1,89 @@
1
+ module KDL
2
+ module V1
3
+ class Value < ::KDL::Value
4
+ module Methods
5
+ def to_s
6
+ return stringify_value unless type
7
+
8
+ "(#{StringDumper.stringify_identifier type})#{stringify_value}"
9
+ end
10
+
11
+ def ==(other)
12
+ return self == other.value if other.is_a?(self.class.superclass)
13
+
14
+ value == other
15
+ end
16
+
17
+ def version
18
+ 1
19
+ end
20
+
21
+ def to_v1
22
+ self
23
+ end
24
+
25
+ def to_v2
26
+ self.class.superclass.new(value, format:, type:)
27
+ end
28
+ end
29
+
30
+ include Methods
31
+
32
+ class Int < ::KDL::Value::Int
33
+ include Methods
34
+ end
35
+
36
+ class Float < ::KDL::Value::Float
37
+ include Methods
38
+
39
+ def stringify_value
40
+ if value.nan? || value.infinite?
41
+ warn "[WARNING] Attempting to serialize non-finite Float using KDL v1"
42
+ return Null.stringify_value
43
+ end
44
+ super
45
+ end
46
+ end
47
+
48
+ class Boolean < ::KDL::Value::Boolean
49
+ include Methods
50
+
51
+ def stringify_value
52
+ value.to_s
53
+ end
54
+ end
55
+
56
+ class String < ::KDL::Value::String
57
+ include Methods
58
+
59
+ def stringify_value
60
+ StringDumper.call(value)
61
+ end
62
+ end
63
+
64
+ class NullImpl < ::KDL::Value::NullImpl
65
+ include Methods
66
+
67
+ def stringify_value
68
+ "null"
69
+ end
70
+
71
+ def to_v2
72
+ type ? ::KDL::Value::NullImpl.new(type:) : ::KDL::Value::Null
73
+ end
74
+ end
75
+ Null = NullImpl.new
76
+
77
+ def self.from(value)
78
+ case value
79
+ when ::String then String.new(value)
80
+ when Integer then Int.new(value)
81
+ when ::Float then Float.new(value)
82
+ when TrueClass, FalseClass then Boolean.new(value)
83
+ when NilClass then Null
84
+ else raise Error("Unsupported value type: #{value.class}")
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
data/lib/kdl/v1.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "kdl/v1/tokenizer"
2
+ require "kdl/v1/document"
3
+ require "kdl/v1/value"
4
+ require "kdl/v1/node"
5
+ require "kdl/v1/string_dumper"
6
+ require "kdl/v1/kdl.tab"
7
+
8
+ module KDL
9
+ module V1
10
+ end
11
+ end
data/lib/kdl/value.rb CHANGED
@@ -15,18 +15,30 @@ module KDL
15
15
  result = parser.call(self, type)
16
16
  return self.as_type(type) if result.nil?
17
17
 
18
- unless result.is_a?(::KDL::Value)
19
- raise ArgumentError, "expected parser to return an instance of ::KDL::Value, got `#{result.class}'"
18
+ unless result.is_a?(::KDL::Value::Custom)
19
+ raise ArgumentError, "expected parser to return an instance of ::KDL::Value::Custom, got `#{result.class}'"
20
20
  end
21
21
 
22
22
  result
23
23
  end
24
24
  end
25
25
 
26
+ def ==(other)
27
+ return self == other.value if other.is_a?(self.class)
28
+
29
+ value == other
30
+ end
31
+
26
32
  def to_s
27
33
  return stringify_value unless type
28
34
 
29
- "(#{StringDumper.stringify_identifier type})#{stringify_value}"
35
+ "(#{StringDumper.call type})#{stringify_value}"
36
+ end
37
+
38
+ def inspect
39
+ return value.inspect unless type
40
+
41
+ "(#{type.inspect})#{value.inspect}"
30
42
  end
31
43
 
32
44
  def stringify_value
@@ -35,18 +47,40 @@ module KDL
35
47
  value.to_s
36
48
  end
37
49
 
50
+ def version
51
+ 2
52
+ end
53
+
54
+ def to_v2
55
+ self
56
+ end
57
+
58
+ def method_missing(name, *args, **kwargs, &block)
59
+ value.public_send(name, *args, **kwargs, &block)
60
+ end
61
+
62
+ def respond_to_missing?(name, include_all = false)
63
+ value.respond_to?(name, include_all)
64
+ end
65
+
38
66
  class Int < Value
39
- def ==(other)
40
- other.is_a?(Int) && value == other.value
67
+ def to_v1
68
+ V1::Value::Int.new(value, format:, type:)
41
69
  end
42
70
  end
43
71
 
44
72
  class Float < Value
45
73
  def ==(other)
46
- other.is_a?(Float) && value == other.value
74
+ return self == other.value if other.is_a?(Float)
75
+ return other.nan? if value.nan?
76
+
77
+ value == other
47
78
  end
48
79
 
49
80
  def stringify_value
81
+ return '#nan' if value.nan?
82
+ return '#inf' if value == ::Float::INFINITY
83
+ return '#-inf' if value == -::Float::INFINITY
50
84
  return super.upcase unless value.is_a?(BigDecimal)
51
85
 
52
86
  sign, digits, _, exponent = value.split
@@ -55,11 +89,22 @@ module KDL
55
89
  s += "E#{exponent.negative? ? '' : '+'}#{exponent - 1}"
56
90
  s
57
91
  end
92
+
93
+ def to_v1
94
+ if value.nan? || value.infinite?
95
+ warn "[WARNING] Converting non-finite Float to KDL v1"
96
+ end
97
+ V1::Value::Float.new(value, format:, type:)
98
+ end
58
99
  end
59
100
 
60
101
  class Boolean < Value
61
- def ==(other)
62
- other.is_a?(Boolean) && value == other.value
102
+ def stringify_value
103
+ "##{value}"
104
+ end
105
+
106
+ def to_v1
107
+ V1::Value::Boolean.new(value, format:, type:)
63
108
  end
64
109
  end
65
110
 
@@ -68,8 +113,8 @@ module KDL
68
113
  StringDumper.call(value)
69
114
  end
70
115
 
71
- def ==(other)
72
- other.is_a?(String) && value == other.value
116
+ def to_v1
117
+ V1::Value::String.new(value, format:, type:)
73
118
  end
74
119
  end
75
120
 
@@ -79,15 +124,39 @@ module KDL
79
124
  end
80
125
 
81
126
  def stringify_value
82
- "null"
127
+ "#null"
83
128
  end
84
129
 
85
130
  def ==(other)
86
- other.is_a?(NullImpl)
131
+ other.is_a?(NullImpl) || other.nil?
132
+ end
133
+
134
+ def to_v1
135
+ type ? V1::Value::NullImpl.new(type:) : V1::Value::Null
87
136
  end
88
137
  end
89
138
  Null = NullImpl.new
90
139
 
140
+ class Custom < Value
141
+ attr_reader :oriinal_value
142
+
143
+ def self.call(value, type)
144
+ new(value, type:)
145
+ end
146
+
147
+ def version
148
+ nil
149
+ end
150
+
151
+ def to_v1
152
+ self
153
+ end
154
+
155
+ def to_v2
156
+ self
157
+ end
158
+ end
159
+
91
160
  def self.from(value)
92
161
  case value
93
162
  when ::String then String.new(value)
data/lib/kdl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module KDL
2
- VERSION = "1.0.5"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/kdl.rb CHANGED
@@ -5,10 +5,49 @@ require "kdl/value"
5
5
  require "kdl/node"
6
6
  require "kdl/string_dumper"
7
7
  require "kdl/types"
8
+ require "kdl/parser_common"
8
9
  require "kdl/kdl.tab"
10
+ require "kdl/v1"
9
11
 
10
12
  module KDL
13
+ class << self
14
+ attr_accessor :default_version
15
+ attr_accessor :default_output_version
16
+ end
17
+
11
18
  def self.parse_document(input, options = {})
12
- Parser.new.parse(input, options)
19
+ warn "[DEPRECATION] `KDL.parse_document' is deprecated. Please use `KDL.parse' instead."
20
+ parse(input, **options)
21
+ end
22
+
23
+ def self.parse(input, version: default_version, output_version: default_output_version, **options)
24
+ case version
25
+ when 2
26
+ Parser.new(output_module: output_module(output_version || 2), **options).parse(input)
27
+ when 1
28
+ V1::Parser.new.parse(input, output_module: output_module(output_version || 1), **options)
29
+ else
30
+ auto_parse(input, output_version:, **options)
31
+ end
32
+ end
33
+
34
+ def self.load_file(filespec, **options)
35
+ parse(File.read(filespec, encoding: Encoding::UTF_8), **options)
36
+ end
37
+
38
+ def self.auto_parse(input, output_version: default_output_version, **options)
39
+ parse(input, version: 2, output_version: output_version || 2, **options)
40
+ rescue => e
41
+ parse(input, version: 1, output_version: output_version || 1, **options) rescue raise e
42
+ end
43
+
44
+ def self.output_module(version)
45
+ case version
46
+ when 1 then KDL::V1
47
+ when 2 then KDL
48
+ else
49
+ warn "Unknown output_version `#{version}', defaulting to v2"
50
+ KDL
51
+ end
13
52
  end
14
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kdl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danielle Smith
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-06 00:00:00.000000000 Z
11
+ date: 2024-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: racc
@@ -92,6 +92,7 @@ files:
92
92
  - lib/kdl/kdl.tab.rb
93
93
  - lib/kdl/kdl.yy
94
94
  - lib/kdl/node.rb
95
+ - lib/kdl/parser_common.rb
95
96
  - lib/kdl/string_dumper.rb
96
97
  - lib/kdl/tokenizer.rb
97
98
  - lib/kdl/types.rb
@@ -116,6 +117,14 @@ files:
116
117
  - lib/kdl/types/url.rb
117
118
  - lib/kdl/types/url_template.rb
118
119
  - lib/kdl/types/uuid.rb
120
+ - lib/kdl/v1.rb
121
+ - lib/kdl/v1/document.rb
122
+ - lib/kdl/v1/kdl.tab.rb
123
+ - lib/kdl/v1/kdl.yy
124
+ - lib/kdl/v1/node.rb
125
+ - lib/kdl/v1/string_dumper.rb
126
+ - lib/kdl/v1/tokenizer.rb
127
+ - lib/kdl/v1/value.rb
119
128
  - lib/kdl/value.rb
120
129
  - lib/kdl/version.rb
121
130
  homepage: https://kdl.dev
@@ -133,14 +142,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
133
142
  requirements:
134
143
  - - ">="
135
144
  - !ruby/object:Gem::Version
136
- version: 2.5.0
145
+ version: 3.1.0
137
146
  required_rubygems_version: !ruby/object:Gem::Requirement
138
147
  requirements:
139
148
  - - ">="
140
149
  - !ruby/object:Gem::Version
141
150
  version: '0'
142
151
  requirements: []
143
- rubygems_version: 3.5.3
152
+ rubygems_version: 3.5.22
144
153
  signing_key:
145
154
  specification_version: 4
146
155
  summary: KDL Document Language