serialbench 0.2.0 → 0.4.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 (74) hide show
  1. checksums.yaml +4 -4
  2. data/.github/scripts/push-to-data.sh +65 -0
  3. data/.github/workflows/benchmark.yml +98 -172
  4. data/.github/workflows/release.yml +68 -13
  5. data/Gemfile +1 -1
  6. data/config/benchmarks/full-json.yml +25 -0
  7. data/config/benchmarks/full-toml.yml +25 -0
  8. data/config/benchmarks/full-xml.yml +26 -0
  9. data/config/benchmarks/full-yaml.yml +25 -0
  10. data/config/benchmarks/full.yml +9 -4
  11. data/lib/serialbench/benchmark_runner.rb +32 -320
  12. data/lib/serialbench/cli/benchmark_cli.rb +1 -1
  13. data/lib/serialbench/cli.rb +0 -12
  14. data/lib/serialbench/models/benchmark_result.rb +2 -0
  15. data/lib/serialbench/models/result_store.rb +0 -38
  16. data/lib/serialbench/models.rb +0 -5
  17. data/lib/serialbench/serializers/base_serializer.rb +11 -3
  18. data/lib/serialbench/serializers/json/base_json_serializer.rb +8 -20
  19. data/lib/serialbench/serializers/json/json_serializer.rb +0 -16
  20. data/lib/serialbench/serializers/json/oj_serializer.rb +2 -17
  21. data/lib/serialbench/serializers/json/yajl_serializer.rb +2 -2
  22. data/lib/serialbench/serializers/toml/base_toml_serializer.rb +8 -29
  23. data/lib/serialbench/serializers/toml/toml_rb_serializer.rb +0 -16
  24. data/lib/serialbench/serializers/toml/tomlib_serializer.rb +0 -4
  25. data/lib/serialbench/serializers/toml/tomlrb_serializer.rb +2 -18
  26. data/lib/serialbench/serializers/xml/base_xml_serializer.rb +10 -26
  27. data/lib/serialbench/serializers/xml/leptris_serializer.rb +13 -10
  28. data/lib/serialbench/serializers/xml/libxml_serializer.rb +4 -9
  29. data/lib/serialbench/serializers/xml/nokogiri_serializer.rb +4 -9
  30. data/lib/serialbench/serializers/xml/oga_serializer.rb +6 -4
  31. data/lib/serialbench/serializers/xml/ox_serializer.rb +2 -2
  32. data/lib/serialbench/serializers/xml/rexml_serializer.rb +5 -12
  33. data/lib/serialbench/serializers/yaml/base_yaml_serializer.rb +1 -9
  34. data/lib/serialbench/serializers/yaml/syck_serializer.rb +0 -8
  35. data/lib/serialbench/test_data.rb +315 -0
  36. data/lib/serialbench/version.rb +1 -1
  37. data/lib/serialbench.rb +2 -1
  38. data/serialbench.gemspec +1 -2
  39. metadata +13 -59
  40. data/lib/serialbench/cli/resultset_cli.rb +0 -301
  41. data/lib/serialbench/models/result_set.rb +0 -79
  42. data/lib/serialbench/site_generator.rb +0 -337
  43. data/lib/serialbench/templates/assets/css/benchmark_report.css +0 -535
  44. data/lib/serialbench/templates/assets/css/format_based.css +0 -474
  45. data/lib/serialbench/templates/assets/css/themes.css +0 -589
  46. data/lib/serialbench/templates/assets/js/chart_helpers.js +0 -411
  47. data/lib/serialbench/templates/assets/js/dashboard.js +0 -795
  48. data/lib/serialbench/templates/assets/js/navigation.js +0 -142
  49. data/lib/serialbench/templates/base.liquid +0 -49
  50. data/lib/serialbench/templates/format_based.liquid +0 -507
  51. data/lib/serialbench/templates/partials/chart_section.liquid +0 -4
  52. data/site/.gitignore +0 -5
  53. data/site/README.md +0 -32
  54. data/site/astro.config.mjs +0 -12
  55. data/site/package-lock.json +0 -6160
  56. data/site/package.json +0 -22
  57. data/site/public/favicon.svg +0 -4
  58. data/site/scripts/gen-sample-data.mjs +0 -154
  59. data/site/src/components/AvailabilityMatrix.astro +0 -61
  60. data/site/src/components/CalibratedLeaderboard.vue +0 -134
  61. data/site/src/components/CitationBox.vue +0 -50
  62. data/site/src/components/DashboardConsole.vue +0 -193
  63. data/site/src/components/FeaturesTable.astro +0 -97
  64. data/site/src/components/MemoryPanel.vue +0 -44
  65. data/site/src/components/OpsChart.vue +0 -135
  66. data/site/src/config.ts +0 -18
  67. data/site/src/layouts/Layout.astro +0 -85
  68. data/site/src/lib/channels.ts +0 -24
  69. data/site/src/lib/dashboard.ts +0 -269
  70. data/site/src/pages/index.astro +0 -44
  71. data/site/src/pages/library/[slug].astro +0 -128
  72. data/site/src/pages/methodology.astro +0 -55
  73. data/site/src/styles/global.css +0 -103
  74. data/site/tsconfig.json +0 -5
@@ -19,41 +19,20 @@ module Serialbench
19
19
  generate(object, options)
20
20
  end
21
21
 
22
+ def capabilities
23
+ super | Set.new(%i[arrays_of_tables inline_tables multiline_strings])
24
+ end
25
+
22
26
  # TOML-specific features
23
27
  def features
24
28
  {
25
- comments: supports_comments?,
26
- arrays_of_tables: supports_arrays_of_tables?,
27
- inline_tables: supports_inline_tables?,
28
- multiline_strings: supports_multiline_strings?
29
+ comments: supports?(:comments),
30
+ arrays_of_tables: supports?(:arrays_of_tables),
31
+ inline_tables: supports?(:inline_tables),
32
+ multiline_strings: supports?(:multiline_strings)
29
33
  }
30
34
  end
31
35
 
32
- def supports_generation?
33
- true
34
- end
35
-
36
- def supports_streaming?
37
- # TOML is typically not streamed due to its structure
38
- false
39
- end
40
-
41
- def supports_comments?
42
- false
43
- end
44
-
45
- def supports_arrays_of_tables?
46
- true
47
- end
48
-
49
- def supports_inline_tables?
50
- true
51
- end
52
-
53
- def supports_multiline_strings?
54
- true
55
- end
56
-
57
36
  # Subclasses should override this to specify their library name
58
37
  def library_require_name
59
38
  raise NotImplementedError, 'Subclasses must implement #library_require_name'
@@ -31,22 +31,6 @@ module Serialbench
31
31
  require 'toml-rb'
32
32
  TomlRB.dump(object)
33
33
  end
34
-
35
- def supports_comments?
36
- false
37
- end
38
-
39
- def supports_arrays_of_tables?
40
- true
41
- end
42
-
43
- def supports_inline_tables?
44
- true
45
- end
46
-
47
- def supports_multiline_strings?
48
- true
49
- end
50
34
  end
51
35
  end
52
36
  end
@@ -28,10 +28,6 @@ module Serialbench
28
28
  1 # Return 1 document processed
29
29
  end
30
30
 
31
- def supports_streaming?
32
- false # TOML is typically parsed as a whole document
33
- end
34
-
35
31
  def version
36
32
  return 'unknown' unless available?
37
33
 
@@ -31,24 +31,8 @@ module Serialbench
31
31
  raise NotImplementedError, 'tomlrb gem does not support TOML generation/dumping'
32
32
  end
33
33
 
34
- def supports_generation?
35
- false
36
- end
37
-
38
- def supports_comments?
39
- false
40
- end
41
-
42
- def supports_arrays_of_tables?
43
- true
44
- end
45
-
46
- def supports_inline_tables?
47
- true
48
- end
49
-
50
- def supports_multiline_strings?
51
- true
34
+ def capabilities
35
+ Set.new(%i[dom parse arrays_of_tables inline_tables multiline_strings])
52
36
  end
53
37
  end
54
38
  end
@@ -23,37 +23,21 @@ module Serialbench
23
23
  generate(document, options)
24
24
  end
25
25
 
26
- # XML-specific features
26
+ def capabilities
27
+ super | Set.new(%i[namespaces])
28
+ end
29
+
30
+ # XML-specific features derive from the capability set
27
31
  def features
28
32
  {
29
- xpath: supports_xpath?,
30
- namespaces: supports_namespaces?,
31
- validation: supports_validation?,
32
- streaming: supports_streaming?,
33
- stax: supports_stax?
33
+ xpath: supports?(:xpath),
34
+ namespaces: supports?(:namespaces),
35
+ validation: supports?(:validation),
36
+ streaming: supports?(:sax) || supports?(:streaming),
37
+ stax: supports?(:stax)
34
38
  }
35
39
  end
36
40
 
37
- def supports_stax?
38
- false
39
- end
40
-
41
- def supports_generation?
42
- true
43
- end
44
-
45
- def supports_xpath?
46
- false
47
- end
48
-
49
- def supports_namespaces?
50
- true
51
- end
52
-
53
- def supports_validation?
54
- false
55
- end
56
-
57
41
  # Check if the XML library is available
58
42
  def available?
59
43
  return @available if defined?(@available)
@@ -12,11 +12,13 @@ module Serialbench
12
12
 
13
13
  def parse(xml_string)
14
14
  require 'leptris'
15
+ require 'leptris/xml'
15
16
  Leptris::XML.parse(xml_string)
16
17
  end
17
18
 
18
19
  def generate(data)
19
20
  require 'leptris'
21
+ require 'leptris/xml'
20
22
  if data.is_a?(Leptris::XML::Document) || data.is_a?(Leptris::XML::Node)
21
23
  data.to_xml(indent: 2)
22
24
  else
@@ -26,6 +28,7 @@ module Serialbench
26
28
 
27
29
  def parse_streaming(xml_string, &block)
28
30
  require 'leptris'
31
+ require 'leptris/xml'
29
32
 
30
33
  handler = StreamingHandler.new(&block)
31
34
  parser = Leptris::XML::SAX::Parser.new(handler)
@@ -33,28 +36,27 @@ module Serialbench
33
36
  handler.elements_processed
34
37
  end
35
38
 
36
- def supports_streaming?
37
- true
39
+ def capabilities
40
+ super | Set.new(%i[xpath sax stax])
38
41
  end
39
42
 
40
- def supports_xpath?
41
- true
43
+ def xpath_query(document, expression)
44
+ require 'leptris'
45
+ require 'leptris/xml'
46
+ result = document.xpath(expression)
47
+ result.size
42
48
  end
43
49
 
44
50
  # leptris-ruby >= 1.6 exposes Leptris::XML::Pull, a StAX-style
45
51
  # cursor (one event per #next). Declared by gem version so the
46
52
  # check never triggers the FFI library load.
47
- def supports_stax?
48
- spec = Gem.loaded_specs['leptris'] || Gem::Specification.find_by_name('leptris')
49
- !spec.nil? && spec.version >= Gem::Version.new('1.6.0')
50
- rescue Gem::LoadError
51
- false
52
- end
53
+
53
54
 
54
55
  def version
55
56
  return 'unknown' unless available?
56
57
 
57
58
  require 'leptris'
59
+ require 'leptris/xml'
58
60
  Leptris::VERSION
59
61
  end
60
62
 
@@ -70,6 +72,7 @@ module Serialbench
70
72
 
71
73
  @available = begin
72
74
  require 'leptris'
75
+ require 'leptris/xml'
73
76
  Leptris::XML.parse('<probe/>')
74
77
  true
75
78
  rescue StandardError, LoadError
@@ -38,17 +38,12 @@ module Serialbench
38
38
  handler.elements_processed
39
39
  end
40
40
 
41
- def supports_xpath?
42
- true
41
+ def capabilities
42
+ super | Set.new(%i[xpath stax sax])
43
43
  end
44
44
 
45
- # The binding exposes a pull-parser cursor (XML::Reader)
46
- def supports_stax?
47
- true
48
- end
49
-
50
- def supports_streaming?
51
- true
45
+ def xpath_query(document, expression)
46
+ document.find(expression).size
52
47
  end
53
48
 
54
49
  def version
@@ -38,17 +38,12 @@ module Serialbench
38
38
  handler.elements_processed
39
39
  end
40
40
 
41
- def supports_xpath?
42
- true
41
+ def capabilities
42
+ super | Set.new(%i[xpath sax stax])
43
43
  end
44
44
 
45
- # The binding exposes a pull-parser cursor (XML::Reader)
46
- def supports_stax?
47
- true
48
- end
49
-
50
- def supports_streaming?
51
- true
45
+ def xpath_query(document, expression)
46
+ document.xpath(expression).size
52
47
  end
53
48
 
54
49
  def version
@@ -38,14 +38,16 @@ module Serialbench
38
38
  handler.elements_processed
39
39
  end
40
40
 
41
- def supports_xpath?
42
- true
41
+ def capabilities
42
+ super | Set.new(%i[xpath sax])
43
43
  end
44
44
 
45
- def supports_streaming?
46
- true
45
+ def xpath_query(document, expression)
46
+ document.xpath(expression).size
47
47
  end
48
48
 
49
+
50
+
49
51
  def version
50
52
  return 'unknown' unless available?
51
53
 
@@ -29,8 +29,8 @@ module Serialbench
29
29
  handler.elements_processed
30
30
  end
31
31
 
32
- def supports_streaming?
33
- true
32
+ def capabilities
33
+ super | Set.new(%i[sax])
34
34
  end
35
35
 
36
36
  def version
@@ -73,20 +73,13 @@ module Serialbench
73
73
  handler.result
74
74
  end
75
75
 
76
- def supports_streaming?
77
- false
76
+ def capabilities
77
+ super | Set.new(%i[xpath])
78
78
  end
79
79
 
80
- def supports_xpath?
81
- true
82
- end
83
-
84
- def supports_namespaces?
85
- true
86
- end
87
-
88
- def supports_validation?
89
- false
80
+ def xpath_query(document, expression)
81
+ require 'rexml/xpath'
82
+ REXML::XPath.match(document, expression).size
90
83
  end
91
84
 
92
85
  private
@@ -11,12 +11,8 @@ module Serialbench
11
11
  :yaml
12
12
  end
13
13
 
14
- def supports_streaming?
15
- false # Most YAML parsers don't support streaming
16
- end
17
-
18
14
  def features
19
- { streaming: supports_streaming? }
15
+ { streaming: supports?(:sax) || supports?(:streaming) }
20
16
  end
21
17
 
22
18
  # Default YAML generation options
@@ -39,10 +35,6 @@ module Serialbench
39
35
  raise NotImplementedError, 'Streaming not supported by this YAML serializer'
40
36
  end
41
37
 
42
- def supports_generation?
43
- true
44
- end
45
-
46
38
  private
47
39
 
48
40
  def require_library(library_name)
@@ -68,14 +68,6 @@ module Serialbench
68
68
  end
69
69
  end
70
70
 
71
- def supports_streaming?
72
- false
73
- end
74
-
75
- def features
76
- %w[parsing generation legacy]
77
- end
78
-
79
71
  def description
80
72
  'Legacy YAML parser (Ruby < 1.9.3)'
81
73
  end
@@ -0,0 +1,315 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Serialbench
4
+ # Fixture documents for every format x size the benchmark engine measures.
5
+ class TestData
6
+ def self.load(config)
7
+ new(config).load
8
+ end
9
+
10
+ def initialize(config)
11
+ @config = config
12
+ end
13
+
14
+ def load
15
+ @config.data_sizes.each_with_object({}) do |size, data|
16
+ data[size] = @config.formats.each_with_object({}) do |format, formats|
17
+ formats[format] = fixture_file(size, format) || generate("#{size}.#{format}")
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def fixture_file(size, format)
25
+ path = "test_data/#{size}.#{format}"
26
+ File.read(path) if File.exist?(path)
27
+ end
28
+
29
+ def generate(key)
30
+ case key
31
+ when 'small.xml' then generate_small_xml
32
+ when 'medium.xml' then generate_medium_xml
33
+ when 'large.xml' then generate_large_xml
34
+ when 'small.json' then generate_small_json
35
+ when 'medium.json' then generate_medium_json
36
+ when 'large.json' then generate_large_json
37
+ when 'small.yaml' then generate_small_yaml
38
+ when 'medium.yaml' then generate_medium_yaml
39
+ when 'large.yaml' then generate_large_yaml
40
+ when 'small.toml' then generate_small_toml
41
+ when 'medium.toml' then generate_medium_toml
42
+ when 'large.toml' then generate_large_toml
43
+ else raise ArgumentError, "no test data generator for #{key}"
44
+ end
45
+ end
46
+
47
+ # Shared data structure generators
48
+ def small_test_data_structure
49
+ {
50
+ config: {
51
+ database: {
52
+ host: 'localhost',
53
+ port: 5432,
54
+ name: 'myapp',
55
+ user: 'admin',
56
+ password: 'secret'
57
+ },
58
+ cache: {
59
+ enabled: true,
60
+ ttl: 3600
61
+ }
62
+ }
63
+ }
64
+ end
65
+
66
+ def medium_test_data_structure
67
+ {
68
+ users: (1..1000).map do |i|
69
+ {
70
+ id: i,
71
+ name: "User #{i}",
72
+ email: "user#{i}@example.com",
73
+ created_at: "2023-01-#{(i % 28) + 1}T10:00:00Z",
74
+ profile: {
75
+ age: 20 + (i % 50),
76
+ city: "City #{i % 100}",
77
+ preferences: {
78
+ theme: i.even? ? 'dark' : 'light',
79
+ notifications: (i % 3).zero?
80
+ }
81
+ }
82
+ }
83
+ end
84
+ }
85
+ end
86
+
87
+ def large_test_data_structure
88
+ {
89
+ dataset: {
90
+ header: {
91
+ created: '2023-01-01T00:00:00Z',
92
+ count: 10_000,
93
+ format: 'data'
94
+ },
95
+ records: (1..10_000).map do |i|
96
+ {
97
+ id: i,
98
+ timestamp: "2023-01-01T#{format('%02d', i % 24)}:#{format('%02d', i % 60)}:#{format('%02d', i % 60)}Z",
99
+ data: {
100
+ field1: "Value #{i}",
101
+ field2: i * 2,
102
+ field3: (i % 100).zero? ? 'special' : 'normal',
103
+ nested: [
104
+ "Item #{i}-1",
105
+ "Item #{i}-2",
106
+ "Item #{i}-3"
107
+ ]
108
+ },
109
+ metadata: {
110
+ source: 'generator',
111
+ version: '1.0',
112
+ checksum: i.to_s(16)
113
+ }
114
+ }
115
+ end
116
+ }
117
+ }
118
+ end
119
+
120
+ # XML test data generators
121
+ def generate_small_xml
122
+ data = small_test_data_structure
123
+ <<~XML
124
+ <?xml version="1.0" encoding="UTF-8"?>
125
+ <config>
126
+ <database>
127
+ <host>#{data[:config][:database][:host]}</host>
128
+ <port>#{data[:config][:database][:port]}</port>
129
+ <name>#{data[:config][:database][:name]}</name>
130
+ <user>#{data[:config][:database][:user]}</user>
131
+ <password>#{data[:config][:database][:password]}</password>
132
+ </database>
133
+ <cache>
134
+ <enabled>#{data[:config][:cache][:enabled]}</enabled>
135
+ <ttl>#{data[:config][:cache][:ttl]}</ttl>
136
+ </cache>
137
+ </config>
138
+ XML
139
+ end
140
+
141
+ def generate_medium_xml
142
+ data = medium_test_data_structure
143
+ users = data[:users].map do |user|
144
+ <<~USER
145
+ <user id="#{user[:id]}">
146
+ <name>#{user[:name]}</name>
147
+ <email>#{user[:email]}</email>
148
+ <created_at>#{user[:created_at]}</created_at>
149
+ <profile>
150
+ <age>#{user[:profile][:age]}</age>
151
+ <city>#{user[:profile][:city]}</city>
152
+ <preferences>
153
+ <theme>#{user[:profile][:preferences][:theme]}</theme>
154
+ <notifications>#{user[:profile][:preferences][:notifications]}</notifications>
155
+ </preferences>
156
+ </profile>
157
+ </user>
158
+ USER
159
+ end.join
160
+
161
+ <<~XML
162
+ <?xml version="1.0" encoding="UTF-8"?>
163
+ <users>
164
+ #{users}
165
+ </users>
166
+ XML
167
+ end
168
+
169
+ def generate_large_xml
170
+ data = large_test_data_structure
171
+ records = data[:dataset][:records].map do |record|
172
+ nested_items = record[:data][:nested].map { |item| " <item>#{item}</item>" }.join("\n")
173
+ <<~RECORD
174
+ <record id="#{record[:id]}">
175
+ <timestamp>#{record[:timestamp]}</timestamp>
176
+ <data>
177
+ <field1>#{record[:data][:field1]}</field1>
178
+ <field2>#{record[:data][:field2]}</field2>
179
+ <field3>#{record[:data][:field3]}</field3>
180
+ <nested>
181
+ #{nested_items}
182
+ </nested>
183
+ </data>
184
+ <metadata>
185
+ <source>#{record[:metadata][:source]}</source>
186
+ <version>#{record[:metadata][:version]}</version>
187
+ <checksum>#{record[:metadata][:checksum]}</checksum>
188
+ </metadata>
189
+ </record>
190
+ RECORD
191
+ end.join
192
+
193
+ <<~XML
194
+ <?xml version="1.0" encoding="UTF-8"?>
195
+ <dataset>
196
+ <header>
197
+ <created>#{data[:dataset][:header][:created]}</created>
198
+ <count>#{data[:dataset][:header][:count]}</count>
199
+ <format>xml</format>
200
+ </header>
201
+ <records>
202
+ #{records}
203
+ </records>
204
+ </dataset>
205
+ XML
206
+ end
207
+
208
+ # JSON test data generators
209
+ def generate_small_json
210
+ JSON.generate(small_test_data_structure)
211
+ end
212
+
213
+ def generate_medium_json
214
+ JSON.generate(medium_test_data_structure)
215
+ end
216
+
217
+ def generate_large_json
218
+ data = large_test_data_structure
219
+ data[:dataset][:header][:format] = 'json'
220
+ JSON.generate(data)
221
+ end
222
+
223
+ # YAML test data generators
224
+ def generate_small_yaml
225
+ small_test_data_structure.to_yaml
226
+ end
227
+
228
+ def generate_medium_yaml
229
+ medium_test_data_structure.to_yaml
230
+ end
231
+
232
+ def generate_large_yaml
233
+ data = large_test_data_structure
234
+ data[:dataset][:header][:format] = 'yaml'
235
+ data.to_yaml
236
+ end
237
+
238
+ # TOML test data generators
239
+ def generate_small_toml
240
+ data = small_test_data_structure
241
+ <<~TOML
242
+ [config]
243
+
244
+ [config.database]
245
+ host = "#{data[:config][:database][:host]}"
246
+ port = #{data[:config][:database][:port]}
247
+ name = "#{data[:config][:database][:name]}"
248
+ user = "#{data[:config][:database][:user]}"
249
+ password = "#{data[:config][:database][:password]}"
250
+
251
+ [config.cache]
252
+ enabled = #{data[:config][:cache][:enabled]}
253
+ ttl = #{data[:config][:cache][:ttl]}
254
+ TOML
255
+ end
256
+
257
+ def generate_medium_toml
258
+ data = medium_test_data_structure
259
+ # Use smaller dataset for TOML due to verbosity
260
+ users = data[:users].first(100)
261
+ users.map do |user|
262
+ <<~USER
263
+ [[users]]
264
+ id = #{user[:id]}
265
+ name = "#{user[:name]}"
266
+ email = "#{user[:email]}"
267
+ created_at = "#{user[:created_at]}"
268
+
269
+ [users.profile]
270
+ age = #{user[:profile][:age]}
271
+ city = "#{user[:profile][:city]}"
272
+
273
+ [users.profile.preferences]
274
+ theme = "#{user[:profile][:preferences][:theme]}"
275
+ notifications = #{user[:profile][:preferences][:notifications]}
276
+ USER
277
+ end.join("\n")
278
+ end
279
+
280
+ def generate_large_toml
281
+ data = large_test_data_structure
282
+ # Use smaller dataset for TOML due to verbosity
283
+ records = data[:dataset][:records].first(1000)
284
+ records_toml = records.map do |record|
285
+ <<~RECORD
286
+ [[dataset.records]]
287
+ id = #{record[:id]}
288
+ timestamp = "#{record[:timestamp]}"
289
+
290
+ [dataset.records.data]
291
+ field1 = "#{record[:data][:field1]}"
292
+ field2 = #{record[:data][:field2]}
293
+ field3 = "#{record[:data][:field3]}"
294
+ nested = #{record[:data][:nested].inspect}
295
+
296
+ [dataset.records.metadata]
297
+ source = "#{record[:metadata][:source]}"
298
+ version = "#{record[:metadata][:version]}"
299
+ checksum = "#{record[:metadata][:checksum]}"
300
+ RECORD
301
+ end.join("\n")
302
+
303
+ <<~TOML
304
+ [dataset]
305
+
306
+ [dataset.header]
307
+ created = "#{data[:dataset][:header][:created]}"
308
+ count = #{records.length}
309
+ format = "toml"
310
+
311
+ #{records_toml}
312
+ TOML
313
+ end
314
+ end
315
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Serialbench
4
- VERSION = '0.2.0'
4
+ VERSION = '0.4.0'
5
5
  end