toon-ruby 0.1.0 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa973e72399a80aea212aefe4128d37ee2f25951962b5f7eb42573c4ba8c297f
4
- data.tar.gz: 29e84d1f0c664914ea03c349922c6a47bcfe97d34374ab724197984cffe96870
3
+ metadata.gz: 969d3f21e6040a3b02a19330c293083c5bfd6d8ca837cdee0857bf72e8f86e7e
4
+ data.tar.gz: 2a5f93ec87c0bf3bf2fcddbfbc63cbbb291f4562fe107a8ba71886b737b70f57
5
5
  SHA512:
6
- metadata.gz: 97a54e987de421c56c2f736c873d567f1ab5f82b1dc022f560d8b3677fe826a7b42b6bbda26a4715bdad3fbf085ef8cff849c8d7f9a0c2892eb6c12436e1f685
7
- data.tar.gz: bb30d9a9f276fa9f0666c45f1238f84ef6c30dd57025627d0e17d36100e600e3b2f408be8b9e667857fca4e6b39a6d7e5c69ce0ee54abb8468268a60e6d10479
6
+ metadata.gz: 9b6beb81830ee688fafc938df44736a172e765d01493508c27e9bdf6f611fba8c6558aa20cb1331700d323dc2a8f667815f65915e5495a84bd337fd30197a332
7
+ data.tar.gz: 8575faca3894db0161f03bfdcedfd303cc9a3763383365c108ae456b53c5a36301042e3704aeeb75f0c2d6064d6603798271046577e5316fee4003677de2a960
data/README.md CHANGED
@@ -30,7 +30,7 @@ users[2]{id,name,role}:
30
30
  Add this line to your application's Gemfile:
31
31
 
32
32
  ```ruby
33
- gem 'toon'
33
+ gem 'toon-ruby'
34
34
  ```
35
35
 
36
36
  And then execute:
@@ -42,7 +42,7 @@ bundle install
42
42
  Or install it yourself as:
43
43
 
44
44
  ```bash
45
- gem install toon
45
+ gem install toon-ruby
46
46
  ```
47
47
 
48
48
  ## Quick Start
@@ -115,7 +115,7 @@ Toon.encode({ 'items' => items })
115
115
  # => "items[2]{sku,qty,price}:\n A1,2,9.99\n B2,1,14.5"
116
116
 
117
117
  # Custom delimiter (tab)
118
- Toon.encode(items, delimiter: "\t")
118
+ Toon.encode({ 'items' => items }, delimiter: "\t")
119
119
  # => "items[2\t]{sku\tqty\tprice}:\n A1\t2\t9.99\n B2\t1\t14.5"
120
120
 
121
121
  # Length marker
@@ -318,7 +318,7 @@ rake
318
318
 
319
319
  ## Contributing
320
320
 
321
- Bug reports and pull requests are welcome on GitHub at https://github.com/johannschopplich/toon.
321
+ Bug reports and pull requests are welcome on GitHub at https://github.com/andrepcg/toon-ruby.
322
322
 
323
323
  ## License
324
324
 
data/lib/toon/encoders.rb CHANGED
@@ -9,20 +9,18 @@ module Toon
9
9
  module Encoders
10
10
  module_function
11
11
 
12
- extend Normalizer
13
- extend Primitives
14
12
 
15
13
  # Encode normalized value
16
14
  def encode_value(value, options)
17
- if json_primitive?(value)
18
- return encode_primitive(value, options[:delimiter])
15
+ if Normalizer.json_primitive?(value)
16
+ return Primitives.encode_primitive(value, options[:delimiter])
19
17
  end
20
18
 
21
19
  writer = LineWriter.new(options[:indent])
22
20
 
23
- if json_array?(value)
21
+ if Normalizer.json_array?(value)
24
22
  encode_array(nil, value, writer, 0, options)
25
- elsif json_object?(value)
23
+ elsif Normalizer.json_object?(value)
26
24
  encode_object(value, writer, 0, options)
27
25
  end
28
26
 
@@ -39,13 +37,13 @@ module Toon
39
37
  end
40
38
 
41
39
  def encode_key_value_pair(key, value, writer, depth, options)
42
- encoded_key = encode_key(key)
40
+ encoded_key = Primitives.encode_key(key)
43
41
 
44
- if json_primitive?(value)
45
- writer.push(depth, "#{encoded_key}: #{encode_primitive(value, options[:delimiter])}")
46
- elsif json_array?(value)
42
+ if Normalizer.json_primitive?(value)
43
+ writer.push(depth, "#{encoded_key}: #{Primitives.encode_primitive(value, options[:delimiter])}")
44
+ elsif Normalizer.json_array?(value)
47
45
  encode_array(key, value, writer, depth, options)
48
- elsif json_object?(value)
46
+ elsif Normalizer.json_object?(value)
49
47
  nested_keys = value.keys
50
48
  if nested_keys.empty?
51
49
  # Empty object
@@ -60,20 +58,20 @@ module Toon
60
58
  # Array encoding
61
59
  def encode_array(key, value, writer, depth, options)
62
60
  if value.empty?
63
- header = format_header(0, key: key, delimiter: options[:delimiter], length_marker: options[:length_marker])
61
+ header = Primitives.format_header(0, key: key, delimiter: options[:delimiter], length_marker: options[:length_marker])
64
62
  writer.push(depth, header)
65
63
  return
66
64
  end
67
65
 
68
66
  # Primitive array
69
- if array_of_primitives?(value)
67
+ if Normalizer.array_of_primitives?(value)
70
68
  encode_inline_primitive_array(key, value, writer, depth, options)
71
69
  return
72
70
  end
73
71
 
74
72
  # Array of arrays (all primitives)
75
- if array_of_arrays?(value)
76
- all_primitive_arrays = value.all? { |arr| array_of_primitives?(arr) }
73
+ if Normalizer.array_of_arrays?(value)
74
+ all_primitive_arrays = value.all? { |arr| Normalizer.array_of_primitives?(arr) }
77
75
  if all_primitive_arrays
78
76
  encode_array_of_arrays_as_list_items(key, value, writer, depth, options)
79
77
  return
@@ -81,7 +79,7 @@ module Toon
81
79
  end
82
80
 
83
81
  # Array of objects
84
- if array_of_objects?(value)
82
+ if Normalizer.array_of_objects?(value)
85
83
  header = detect_tabular_header(value)
86
84
  if header
87
85
  encode_array_of_objects_as_tabular(key, value, header, writer, depth, options)
@@ -96,27 +94,27 @@ module Toon
96
94
  end
97
95
 
98
96
  # Primitive array encoding (inline)
99
- def encode_inline_primitive_array(prefix, values, writer, depth, options)
100
- formatted = format_inline_array(values, options[:delimiter], prefix, options[:length_marker])
97
+ def encode_inline_primitive_array(key, values, writer, depth, options)
98
+ formatted = format_inline_array(values, options[:delimiter], key, options[:length_marker])
101
99
  writer.push(depth, formatted)
102
100
  end
103
101
 
104
102
  # Array of arrays (expanded format)
105
- def encode_array_of_arrays_as_list_items(prefix, values, writer, depth, options)
106
- header = format_header(values.length, key: prefix, delimiter: options[:delimiter], length_marker: options[:length_marker])
103
+ def encode_array_of_arrays_as_list_items(key, values, writer, depth, options)
104
+ header = Primitives.format_header(values.length, key: key, delimiter: options[:delimiter], length_marker: options[:length_marker])
107
105
  writer.push(depth, header)
108
106
 
109
107
  values.each do |arr|
110
- if array_of_primitives?(arr)
108
+ if Normalizer.array_of_primitives?(arr)
111
109
  inline = format_inline_array(arr, options[:delimiter], nil, options[:length_marker])
112
110
  writer.push(depth + 1, "#{LIST_ITEM_PREFIX}#{inline}")
113
111
  end
114
112
  end
115
113
  end
116
114
 
117
- def format_inline_array(values, delimiter, prefix = nil, length_marker = false)
118
- header = format_header(values.length, key: prefix, delimiter: delimiter, length_marker: length_marker)
119
- joined_value = join_encoded_values(values, delimiter)
115
+ def format_inline_array(values, delimiter, key = nil, length_marker = false)
116
+ header = Primitives.format_header(values.length, key: key, delimiter: delimiter, length_marker: length_marker)
117
+ joined_value = Primitives.join_encoded_values(values, delimiter)
120
118
  # Only add space if there are values
121
119
  if values.empty?
122
120
  header
@@ -126,8 +124,8 @@ module Toon
126
124
  end
127
125
 
128
126
  # Array of objects (tabular format)
129
- def encode_array_of_objects_as_tabular(prefix, rows, header, writer, depth, options)
130
- header_str = format_header(rows.length, key: prefix, fields: header, delimiter: options[:delimiter], length_marker: options[:length_marker])
127
+ def encode_array_of_objects_as_tabular(key, rows, header, writer, depth, options)
128
+ header_str = Primitives.format_header(rows.length, key: key, fields: header, delimiter: options[:delimiter], length_marker: options[:length_marker])
131
129
  writer.push(depth, header_str)
132
130
 
133
131
  write_tabular_rows(rows, header, writer, depth + 1, options)
@@ -156,7 +154,7 @@ module Toon
156
154
 
157
155
  # Check that all header keys exist in the row and all values are primitives
158
156
  header.all? do |key|
159
- row.key?(key) && json_primitive?(row[key])
157
+ row.key?(key) && Normalizer.json_primitive?(row[key])
160
158
  end
161
159
  end
162
160
  end
@@ -164,27 +162,27 @@ module Toon
164
162
  def write_tabular_rows(rows, header, writer, depth, options)
165
163
  rows.each do |row|
166
164
  values = header.map { |key| row[key] }
167
- joined_value = join_encoded_values(values, options[:delimiter])
165
+ joined_value = Primitives.join_encoded_values(values, options[:delimiter])
168
166
  writer.push(depth, joined_value)
169
167
  end
170
168
  end
171
169
 
172
170
  # Array of objects (expanded format)
173
- def encode_mixed_array_as_list_items(prefix, items, writer, depth, options)
174
- header = format_header(items.length, key: prefix, delimiter: options[:delimiter], length_marker: options[:length_marker])
171
+ def encode_mixed_array_as_list_items(key, items, writer, depth, options)
172
+ header = Primitives.format_header(items.length, key: key, delimiter: options[:delimiter], length_marker: options[:length_marker])
175
173
  writer.push(depth, header)
176
174
 
177
175
  items.each do |item|
178
- if json_primitive?(item)
176
+ if Normalizer.json_primitive?(item)
179
177
  # Direct primitive as list item
180
- writer.push(depth + 1, "#{LIST_ITEM_PREFIX}#{encode_primitive(item, options[:delimiter])}")
181
- elsif json_array?(item)
178
+ writer.push(depth + 1, "#{LIST_ITEM_PREFIX}#{Primitives.encode_primitive(item, options[:delimiter])}")
179
+ elsif Normalizer.json_array?(item)
182
180
  # Direct array as list item
183
- if array_of_primitives?(item)
181
+ if Normalizer.array_of_primitives?(item)
184
182
  inline = format_inline_array(item, options[:delimiter], nil, options[:length_marker])
185
183
  writer.push(depth + 1, "#{LIST_ITEM_PREFIX}#{inline}")
186
184
  end
187
- elsif json_object?(item)
185
+ elsif Normalizer.json_object?(item)
188
186
  # Object as list item
189
187
  encode_object_as_list_item(item, writer, depth + 1, options)
190
188
  end
@@ -200,22 +198,22 @@ module Toon
200
198
 
201
199
  # First key-value on the same line as "- "
202
200
  first_key = keys[0]
203
- encoded_key = encode_key(first_key)
201
+ encoded_key = Primitives.encode_key(first_key)
204
202
  first_value = obj[first_key]
205
203
 
206
- if json_primitive?(first_value)
207
- writer.push(depth, "#{LIST_ITEM_PREFIX}#{encoded_key}: #{encode_primitive(first_value, options[:delimiter])}")
208
- elsif json_array?(first_value)
209
- if array_of_primitives?(first_value)
204
+ if Normalizer.json_primitive?(first_value)
205
+ writer.push(depth, "#{LIST_ITEM_PREFIX}#{encoded_key}: #{Primitives.encode_primitive(first_value, options[:delimiter])}")
206
+ elsif Normalizer.json_array?(first_value)
207
+ if Normalizer.array_of_primitives?(first_value)
210
208
  # Inline format for primitive arrays
211
209
  formatted = format_inline_array(first_value, options[:delimiter], first_key, options[:length_marker])
212
210
  writer.push(depth, "#{LIST_ITEM_PREFIX}#{formatted}")
213
- elsif array_of_objects?(first_value)
211
+ elsif Normalizer.array_of_objects?(first_value)
214
212
  # Check if array of objects can use tabular format
215
213
  header = detect_tabular_header(first_value)
216
214
  if header
217
215
  # Tabular format for uniform arrays of objects
218
- header_str = format_header(first_value.length, key: first_key, fields: header, delimiter: options[:delimiter], length_marker: options[:length_marker])
216
+ header_str = Primitives.format_header(first_value.length, key: first_key, fields: header, delimiter: options[:delimiter], length_marker: options[:length_marker])
219
217
  writer.push(depth, "#{LIST_ITEM_PREFIX}#{header_str}")
220
218
  write_tabular_rows(first_value, header, writer, depth + 1, options)
221
219
  else
@@ -231,17 +229,17 @@ module Toon
231
229
 
232
230
  # Encode array contents at depth + 1
233
231
  first_value.each do |item|
234
- if json_primitive?(item)
235
- writer.push(depth + 1, "#{LIST_ITEM_PREFIX}#{encode_primitive(item, options[:delimiter])}")
236
- elsif json_array?(item) && array_of_primitives?(item)
232
+ if Normalizer.json_primitive?(item)
233
+ writer.push(depth + 1, "#{LIST_ITEM_PREFIX}#{Primitives.encode_primitive(item, options[:delimiter])}")
234
+ elsif Normalizer.json_array?(item) && Normalizer.array_of_primitives?(item)
237
235
  inline = format_inline_array(item, options[:delimiter], nil, options[:length_marker])
238
236
  writer.push(depth + 1, "#{LIST_ITEM_PREFIX}#{inline}")
239
- elsif json_object?(item)
237
+ elsif Normalizer.json_object?(item)
240
238
  encode_object_as_list_item(item, writer, depth + 1, options)
241
239
  end
242
240
  end
243
241
  end
244
- elsif json_object?(first_value)
242
+ elsif Normalizer.json_object?(first_value)
245
243
  nested_keys = first_value.keys
246
244
  if nested_keys.empty?
247
245
  writer.push(depth, "#{LIST_ITEM_PREFIX}#{encoded_key}:")
@@ -9,14 +9,12 @@ module Toon
9
9
 
10
10
  # Normalization (unknown → JSON-compatible value)
11
11
  def normalize_value(value)
12
- # null
13
- return nil if value.nil?
14
-
15
- # Primitives
16
- return value if value.is_a?(String) || value.is_a?(TrueClass) || value.is_a?(FalseClass)
17
-
18
- # Numbers: handle special cases
19
- if value.is_a?(Numeric)
12
+ case value
13
+ when nil
14
+ nil
15
+ when String, TrueClass, FalseClass
16
+ value
17
+ when Numeric
20
18
  # Float special cases
21
19
  if value.is_a?(Float)
22
20
  # -0.0 becomes 0
@@ -24,48 +22,25 @@ module Toon
24
22
  # NaN and Infinity become nil
25
23
  return nil unless value.finite?
26
24
  end
27
- return value
28
- end
29
-
30
- # Symbol → string
31
- return value.to_s if value.is_a?(Symbol)
32
-
33
- # Time → ISO8601 string
34
- if value.is_a?(Time)
35
- return value.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
36
- end
37
-
38
- # DateTime → ISO8601 string
39
- if value.respond_to?(:iso8601) && !value.is_a?(Date)
40
- return value.iso8601
41
- end
42
-
43
- # Date ISO8601 string
44
- if value.is_a?(Date)
45
- return value.to_time.utc.iso8601
25
+ value
26
+ when Symbol
27
+ value.to_s
28
+ when Time
29
+ value.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
30
+ when ->(v) { v.respond_to?(:iso8601) && !v.is_a?(Date) }
31
+ value.iso8601
32
+ when Date
33
+ value.to_time.utc.iso8601
34
+ when Array
35
+ value.map { |v| normalize_value(v) }
36
+ when Set
37
+ value.to_a.map { |v| normalize_value(v) }
38
+ when Hash
39
+ value.each_with_object({}) { |(k, v), h| h[k.to_s] = normalize_value(v) }
40
+ else
41
+ # Fallback: anything else becomes nil (functions, etc.)
42
+ nil
46
43
  end
47
-
48
- # Array
49
- if value.is_a?(Array)
50
- return value.map { |v| normalize_value(v) }
51
- end
52
-
53
- # Set → array
54
- if value.is_a?(Set)
55
- return value.to_a.map { |v| normalize_value(v) }
56
- end
57
-
58
- # Hash/object
59
- if value.is_a?(Hash)
60
- result = {}
61
- value.each do |k, v|
62
- result[k.to_s] = normalize_value(v)
63
- end
64
- return result
65
- end
66
-
67
- # Fallback: anything else becomes nil (functions, etc.)
68
- nil
69
44
  end
70
45
 
71
46
  # Type guards
data/lib/toon/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Toon
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  end
data/lib/toon/writer.rb CHANGED
@@ -16,4 +16,5 @@ module Toon
16
16
  @lines.join("\n")
17
17
  end
18
18
  end
19
+ private_constant :LineWriter
19
20
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: toon-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Perdigão