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 +4 -4
- data/README.md +4 -4
- data/lib/toon/encoders.rb +45 -47
- data/lib/toon/normalizer.rb +24 -49
- data/lib/toon/version.rb +1 -1
- data/lib/toon/writer.rb +1 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 969d3f21e6040a3b02a19330c293083c5bfd6d8ca837cdee0857bf72e8f86e7e
|
|
4
|
+
data.tar.gz: 2a5f93ec87c0bf3bf2fcddbfbc63cbbb291f4562fe107a8ba71886b737b70f57
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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/
|
|
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(
|
|
100
|
-
formatted = format_inline_array(values, options[:delimiter],
|
|
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(
|
|
106
|
-
header = format_header(values.length, key:
|
|
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,
|
|
118
|
-
header = format_header(values.length, key:
|
|
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(
|
|
130
|
-
header_str = format_header(rows.length, key:
|
|
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(
|
|
174
|
-
header = format_header(items.length, key:
|
|
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}:")
|
data/lib/toon/normalizer.rb
CHANGED
|
@@ -9,14 +9,12 @@ module Toon
|
|
|
9
9
|
|
|
10
10
|
# Normalization (unknown → JSON-compatible value)
|
|
11
11
|
def normalize_value(value)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
data/lib/toon/writer.rb
CHANGED