kdl 1.0.6 → 2.0.1

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +8 -1
  3. data/.gitignore +1 -0
  4. data/.gitmodules +4 -0
  5. data/Gemfile +6 -1
  6. data/README.md +67 -7
  7. data/Rakefile +6 -1
  8. data/bin/kdl +1 -1
  9. data/kdl.gemspec +2 -2
  10. data/lib/kdl/document.rb +60 -2
  11. data/lib/kdl/error.rb +24 -0
  12. data/lib/kdl/kdl.tab.rb +305 -231
  13. data/lib/kdl/kdl.yy +57 -49
  14. data/lib/kdl/node.rb +116 -13
  15. data/lib/kdl/parser_common.rb +28 -0
  16. data/lib/kdl/string_dumper.rb +32 -33
  17. data/lib/kdl/tokenizer.rb +387 -136
  18. data/lib/kdl/types/base64.rb +3 -1
  19. data/lib/kdl/types/country/iso3166_countries.rb +3 -1
  20. data/lib/kdl/types/country/iso3166_subdivisions.rb +3 -1
  21. data/lib/kdl/types/country.rb +4 -2
  22. data/lib/kdl/types/currency/iso4217_currencies.rb +3 -1
  23. data/lib/kdl/types/currency.rb +3 -1
  24. data/lib/kdl/types/date_time.rb +5 -3
  25. data/lib/kdl/types/decimal.rb +3 -1
  26. data/lib/kdl/types/duration/iso8601_parser.rb +3 -1
  27. data/lib/kdl/types/duration.rb +3 -1
  28. data/lib/kdl/types/email/parser.rb +10 -8
  29. data/lib/kdl/types/email.rb +3 -1
  30. data/lib/kdl/types/hostname/validator.rb +3 -1
  31. data/lib/kdl/types/hostname.rb +3 -1
  32. data/lib/kdl/types/ip.rb +3 -1
  33. data/lib/kdl/types/irl/parser.rb +10 -8
  34. data/lib/kdl/types/irl.rb +3 -1
  35. data/lib/kdl/types/regex.rb +3 -1
  36. data/lib/kdl/types/url.rb +3 -1
  37. data/lib/kdl/types/url_template.rb +6 -4
  38. data/lib/kdl/types/uuid.rb +3 -1
  39. data/lib/kdl/types.rb +2 -0
  40. data/lib/kdl/v1/document.rb +19 -0
  41. data/lib/kdl/v1/kdl.tab.rb +594 -0
  42. data/lib/kdl/v1/kdl.yy +89 -0
  43. data/lib/kdl/v1/node.rb +32 -0
  44. data/lib/kdl/v1/string_dumper.rb +30 -0
  45. data/lib/kdl/v1/tokenizer.rb +298 -0
  46. data/lib/kdl/v1/value.rb +91 -0
  47. data/lib/kdl/v1.rb +13 -0
  48. data/lib/kdl/value.rb +87 -15
  49. data/lib/kdl/version.rb +3 -1
  50. data/lib/kdl.rb +47 -1
  51. metadata +14 -7
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'base64'
2
4
 
3
5
  module KDL
4
6
  module Types
5
- class Base64 < Value
7
+ class Base64 < Value::Custom
6
8
  RGX = /^[A-Za-z0-9+\/=]+$/.freeze
7
9
 
8
10
  def self.call(value, type = 'base64')
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KDL
2
4
  module Types
3
- class Country < Value
5
+ class Country < Value::Custom
4
6
  # From: https://en.wikipedia.org/wiki/ISO_3166-1#Current_codes
5
7
  COUNTRIES3 = {
6
8
  'AFG' => { alpha3: 'AFG', alpha2: 'AF', numeric_code: 4, name: 'Afghanistan' }.freeze,
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KDL
2
4
  module Types
3
- class CountrySubdivision < Value
5
+ class CountrySubdivision < Value::Custom
4
6
  # From: https://en.wikipedia.org/wiki/ISO_3166-2#Current_codes
5
7
  COUNTRY_SUBDIVISIONS = {
6
8
  "AD" => {
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'kdl/types/country/iso3166_countries'
2
4
  require 'kdl/types/country/iso3166_subdivisions'
3
5
 
4
6
  module KDL
5
7
  module Types
6
- class Country < Value
8
+ class Country < Value::Custom
7
9
  attr_reader :name, :alpha2, :alpha3, :numeric_code
8
10
 
9
11
  def initialize(value, format: nil, type: 'country-3')
@@ -42,7 +44,7 @@ module KDL
42
44
  end
43
45
  MAPPING['country-2'] = Country2
44
46
 
45
- class CountrySubdivision < Value
47
+ class CountrySubdivision < Value::Custom
46
48
  attr_reader :country, :name
47
49
 
48
50
  def initialize(value, type: 'country-subdivision', country:, name:, **kwargs)
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KDL
2
4
  module Types
3
- class Currency < Value
5
+ class Currency < Value::Custom
4
6
  # From https://en.wikipedia.org/wiki/ISO_4217#Active_codes
5
7
  CURRENCIES = {
6
8
  'AED' => { numeric_code: 784, minor_unit: 2, name: 'United Arab Emirates dirham' }.freeze,
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'kdl/types/currency/iso4217_currencies'
2
4
 
3
5
  module KDL
4
6
  module Types
5
- class Currency < Value
7
+ class Currency < Value::Custom
6
8
  attr_reader :numeric_code, :minor_unit, :name
7
9
 
8
10
  def initialize(value, format: nil, type: 'currency')
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'time'
2
4
 
3
5
  module KDL
4
6
  module Types
5
- class DateTime < Value
7
+ class DateTime < Value::Custom
6
8
  def self.call(value, type = 'date-time')
7
9
  return nil unless value.is_a? ::KDL::Value::String
8
10
 
@@ -12,7 +14,7 @@ module KDL
12
14
  end
13
15
  MAPPING['date-time'] = DateTime
14
16
 
15
- class Time < Value
17
+ class Time < Value::Custom
16
18
  # TODO: this is not a perfect ISO8601 time string
17
19
  REGEX = /^T?((?:2[0-3]|[01][0-9]):[0-5][0-9]:[0-5][0-9](?:\.[0-9]+)?(?:Z|[+-]\d\d:\d\d)?)$/
18
20
 
@@ -28,7 +30,7 @@ module KDL
28
30
  end
29
31
  MAPPING['time'] = Time
30
32
 
31
- class Date < Value
33
+ class Date < Value::Custom
32
34
  def self.call(value, type = 'date')
33
35
  return nil unless value.is_a? ::KDL::Value::String
34
36
 
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KDL
2
4
  module Types
3
- class Decimal < Value
5
+ class Decimal < Value::Custom
4
6
  def self.call(value, type = 'decimal')
5
7
  return nil unless value.is_a? ::KDL::Value::String
6
8
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Shamelessly borrowed from https://github.com/rails/rails/tree/main/activesupport
2
4
  #
3
5
  # Copyright (c) 2005-2021 David Heinemeier Hansson
@@ -25,7 +27,7 @@ require 'strscan'
25
27
 
26
28
  module KDL
27
29
  module Types
28
- class Duration < Value
30
+ class Duration < Value::Custom
29
31
  # Parses a string formatted according to ISO 8601 Duration into the hash.
30
32
  #
31
33
  # See {ISO 8601}[https://en.wikipedia.org/wiki/ISO_8601#Durations] for more information.
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'kdl/types/duration/iso8601_parser'
2
4
 
3
5
  module KDL
4
6
  module Types
5
- class Duration < Value
7
+ class Duration < Value::Custom
6
8
  attr_reader :years, :months, :weeks, :days, :hours, :minutes, :seconds
7
9
 
8
10
  def initialize(parts = {}, format: nil, type: 'duration')
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../hostname/validator'
2
4
 
3
5
  module KDL
4
6
  module Types
5
- class Email < Value
7
+ class Email < Value::Custom
6
8
  class Parser
7
9
  def initialize(string, idn: false)
8
10
  @string = string
@@ -11,7 +13,7 @@ module KDL
11
13
  end
12
14
 
13
15
  def parse
14
- local = ''
16
+ local = +''
15
17
  unicode_domain = nil
16
18
  domain = nil
17
19
  context = :start
@@ -23,7 +25,7 @@ module KDL
23
25
  when :part
24
26
  case context
25
27
  when :start, :after_dot
26
- local += value
28
+ local << value
27
29
  context = :after_part
28
30
  else
29
31
  raise ArgumentError, "invalid email #{@string} (unexpected part #{value} at #{context})"
@@ -31,7 +33,7 @@ module KDL
31
33
  when :dot
32
34
  case context
33
35
  when :after_part
34
- local += value
36
+ local << value
35
37
  context = :after_dot
36
38
  else
37
39
  raise ArgumentError, "invalid email #{@string} (unexpected dot at #{context})"
@@ -91,7 +93,7 @@ module KDL
91
93
  end
92
94
  end
93
95
  @context = nil
94
- @buffer = ''
96
+ @buffer = +''
95
97
  loop do
96
98
  c = @string[@index]
97
99
  return [:end, nil] if c.nil?
@@ -111,7 +113,7 @@ module KDL
111
113
  @index += 1
112
114
  when local_part_chars
113
115
  @context = :part
114
- @buffer += c
116
+ @buffer << c
115
117
  @index += 1
116
118
  else
117
119
  raise ArgumentError, "invalid email #{@string} (unexpected #{c})"
@@ -119,7 +121,7 @@ module KDL
119
121
  when :part
120
122
  case c
121
123
  when local_part_chars
122
- @buffer += c
124
+ @buffer << c
123
125
  @index += 1
124
126
  when '.', '@'
125
127
  return [:part, @buffer]
@@ -135,7 +137,7 @@ module KDL
135
137
  @index += 1
136
138
  return [:part, @buffer]
137
139
  else
138
- @buffer += c
140
+ @buffer << c
139
141
  @index += 1
140
142
  end
141
143
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative './email/parser'
2
4
 
3
5
  module KDL
4
6
  module Types
5
- class Email < Value
7
+ class Email < Value::Custom
6
8
  attr_reader :local, :domain
7
9
 
8
10
  def initialize(value, local:, domain:, **kwargs)
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'simpleidn'
2
4
 
3
5
  module KDL
4
6
  module Types
5
- class Hostname < Value
7
+ class Hostname < Value::Custom
6
8
  class Validator
7
9
  PART_RGX = /^[a-z0-9_][a-z0-9_\-]{0,62}$/i
8
10
 
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative './hostname/validator'
2
4
 
3
5
  module KDL
4
6
  module Types
5
- class Hostname < Value
7
+ class Hostname < Value::Custom
6
8
  def self.call(value, type = 'hostname')
7
9
  return nil unless value.is_a? ::KDL::Value::String
8
10
 
data/lib/kdl/types/ip.rb CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KDL
2
4
  module Types
3
- class IP < Value
5
+ class IP < Value::Custom
4
6
  def self.call(value, type = ip_type)
5
7
  return nil unless value.is_a? ::KDL::Value::String
6
8
 
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KDL
2
4
  module Types
3
- class IRLReference < Value
5
+ class IRLReference < Value::Custom
4
6
  class Parser
5
7
  RGX = /^(?:(?:([a-z][a-z0-9+.\-]+)):\/\/([^@]+@)?([^\/?#]+)?)?(\/?[^?#]*)?(?:\?([^#]*))?(?:#(.*))?$/i.freeze
6
8
  PERCENT_RGX = /%[a-f0-9]{2}/i.freeze
@@ -96,13 +98,13 @@ module KDL
96
98
  end
97
99
 
98
100
  def self.build_uri_string(scheme, auth, domain, path, search, hash)
99
- string = ''
100
- string += "#{scheme}://" if scheme
101
- string += auth if auth
102
- string += domain if domain
103
- string += path if path
104
- string += "?#{search}" if search
105
- string += "##{hash}" if hash
101
+ string = +''
102
+ string << "#{scheme}://" if scheme
103
+ string << auth if auth
104
+ string << domain if domain
105
+ string << path if path
106
+ string << "?#{search}" if search
107
+ string << "##{hash}" if hash
106
108
  string
107
109
  end
108
110
  end
data/lib/kdl/types/irl.rb CHANGED
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative './irl/parser'
2
4
 
3
5
  module KDL
4
6
  module Types
5
- class IRLReference < Value
7
+ class IRLReference < Value::Custom
6
8
  attr_reader :unicode_value,
7
9
  :unicode_domain,
8
10
  :unicode_path,
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KDL
2
4
  module Types
3
- class Regex < Value
5
+ class Regex < Value::Custom
4
6
  def self.call(value, type = 'regex')
5
7
  return nil unless value.is_a? ::KDL::Value::String
6
8
 
data/lib/kdl/types/url.rb CHANGED
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KDL
2
4
  module Types
3
- class URLReference < Value
5
+ class URLReference < Value::Custom
4
6
  def self.call(value, type = 'url-reference')
5
7
  return nil unless value.is_a? ::KDL::Value::String
6
8
 
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uri'
2
4
 
3
5
  module KDL
4
6
  module Types
5
- class URLTemplate < Value
7
+ class URLTemplate < Value::Custom
6
8
  UNRESERVED = /[a-zA-Z0-9\-._~]/.freeze
7
9
  RESERVED = %r{[:/?#\[\]@!$&'()*+,;=]}.freeze
8
10
 
@@ -39,7 +41,7 @@ module KDL
39
41
  end
40
42
 
41
43
  def next_token
42
- buffer = ''
44
+ buffer = +''
43
45
  context = nil
44
46
  expansion_type = nil
45
47
  loop do
@@ -49,7 +51,7 @@ module KDL
49
51
  case c
50
52
  when '{'
51
53
  context = :expansion
52
- buffer = ''
54
+ buffer = +''
53
55
  n = @string[@index + 1]
54
56
  expansion_type = case n
55
57
  when '+' then ReservedExpansion
@@ -64,7 +66,7 @@ module KDL
64
66
  @index += (expansion_type == StringExpansion ? 1 : 2)
65
67
  when nil then return nil
66
68
  else
67
- buffer = c
69
+ buffer = +c
68
70
  @index += 1
69
71
  context = :literal
70
72
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KDL
2
4
  module Types
3
- class UUID < Value
5
+ class UUID < Value::Custom
4
6
  RGX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
5
7
 
6
8
  def self.call(value, type = 'uuid')
data/lib/kdl/types.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module KDL
2
4
  module Types
3
5
  MAPPING = {}
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KDL
4
+ module V1
5
+ class Document < ::KDL::Document
6
+ def version
7
+ 1
8
+ end
9
+
10
+ def to_v1
11
+ self
12
+ end
13
+
14
+ def to_v2
15
+ ::KDL::Document.new(nodes.map(&:to_v2))
16
+ end
17
+ end
18
+ end
19
+ end