turbostreamer 1.0 → 1.1.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.
- checksums.yaml +4 -4
- data/lib/turbostreamer/encoders/oj.rb +145 -0
- data/lib/turbostreamer/encoders/wankel.rb +23 -22
- data/lib/turbostreamer/version.rb +2 -2
- data/lib/turbostreamer.rb +43 -32
- metadata +45 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69bc4c5ae74ca34c77d4efec5dcea7f3cc13121d
|
4
|
+
data.tar.gz: 8061f78d59db2cbab4fbab6903e690f499b63bbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b921bb41799b13110dd30b3be833312f6a8049ee31dae19559ce7016b38b84b43bf304199172b10c932b0e8211ecd8574e2081100f109cf93d7ab27416fdf153
|
7
|
+
data.tar.gz: 1bf7d693f46fd09c78b2f7c3339acda1978a52356177ff0ddf1a1e680d4c5621cd9a1d7047ebd83d12354790b9f03237cf478f47e446303d3893c9b95eb833ab
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require "oj"
|
2
|
+
|
3
|
+
class TurboStreamer
|
4
|
+
class OjEncoder
|
5
|
+
|
6
|
+
attr_reader :output
|
7
|
+
|
8
|
+
def initialize(io, options={})
|
9
|
+
@stack = []
|
10
|
+
@indexes = []
|
11
|
+
|
12
|
+
@options = {mode: :json}.merge(options)
|
13
|
+
|
14
|
+
@output = io
|
15
|
+
@stream_writer = ::Oj::StreamWriter.new(io, @options)
|
16
|
+
@write_comma_on_next_push = false
|
17
|
+
end
|
18
|
+
|
19
|
+
def key(k)
|
20
|
+
if @write_comma_on_next_push && (@stack.last == :array || @stack.last == :map)
|
21
|
+
@stream_writer.flush
|
22
|
+
@output.write(",".freeze)
|
23
|
+
@write_comma_on_next_push = false
|
24
|
+
end
|
25
|
+
@stream_writer.push_key(k)
|
26
|
+
end
|
27
|
+
|
28
|
+
def value(v)
|
29
|
+
if @stack.last == :array || @stack.last == :map
|
30
|
+
@indexes[-1] += 1
|
31
|
+
|
32
|
+
if @write_comma_on_next_push
|
33
|
+
@stream_writer.flush
|
34
|
+
@output.write(",".freeze)
|
35
|
+
@write_comma_on_next_push = false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
@stream_writer.push_value(v)
|
39
|
+
end
|
40
|
+
|
41
|
+
def map_open
|
42
|
+
@stack << :map
|
43
|
+
@indexes << 0
|
44
|
+
if @write_comma_on_next_push
|
45
|
+
@stream_writer.flush
|
46
|
+
@output.write(",".freeze)
|
47
|
+
@write_comma_on_next_push = false
|
48
|
+
end
|
49
|
+
@stream_writer.push_object
|
50
|
+
end
|
51
|
+
|
52
|
+
def map_close
|
53
|
+
@indexes.pop
|
54
|
+
@stack.pop
|
55
|
+
@stream_writer.pop
|
56
|
+
end
|
57
|
+
|
58
|
+
def array_open
|
59
|
+
@stack << :array
|
60
|
+
@indexes << 0
|
61
|
+
if @write_comma_on_next_push
|
62
|
+
@stream_writer.flush
|
63
|
+
@output.write(",".freeze)
|
64
|
+
@write_comma_on_next_push = false
|
65
|
+
end
|
66
|
+
@stream_writer.push_array
|
67
|
+
end
|
68
|
+
|
69
|
+
def array_close
|
70
|
+
@indexes.pop
|
71
|
+
@stack.pop
|
72
|
+
@stream_writer.pop
|
73
|
+
end
|
74
|
+
|
75
|
+
def inject(string)
|
76
|
+
@stream_writer.flush
|
77
|
+
|
78
|
+
if @write_comma_on_next_push
|
79
|
+
@output.write(",".freeze)
|
80
|
+
@write_comma_on_next_push = false
|
81
|
+
end
|
82
|
+
|
83
|
+
if @stack.last == :array && !string.empty?
|
84
|
+
if @indexes.last > 0
|
85
|
+
self.output.write(",")
|
86
|
+
else
|
87
|
+
@write_comma_on_next_push = true
|
88
|
+
end
|
89
|
+
@indexes[-1] += 1
|
90
|
+
elsif @stack.last == :map && !string.empty?
|
91
|
+
if @indexes.last > 0
|
92
|
+
self.output.write(",")
|
93
|
+
else
|
94
|
+
@write_comma_on_next_push = true
|
95
|
+
end
|
96
|
+
@indexes[-1] += 1
|
97
|
+
end
|
98
|
+
|
99
|
+
self.output.write(string.sub(/\A,/, ''.freeze).chomp(",".freeze).strip)
|
100
|
+
end
|
101
|
+
|
102
|
+
def capture(to=nil)
|
103
|
+
@stream_writer.flush
|
104
|
+
|
105
|
+
old_writer = @stream_writer
|
106
|
+
old_output = @output
|
107
|
+
@indexes << 0
|
108
|
+
|
109
|
+
@output = (to || ::StringIO.new)
|
110
|
+
@stream_writer = ::Oj::StreamWriter.new(@output, @options)
|
111
|
+
|
112
|
+
# This is to prevent error from OJ streamer
|
113
|
+
# We will strip the brackets afterward
|
114
|
+
if @stack.last == :map
|
115
|
+
@stream_writer.push_object
|
116
|
+
elsif @stack.last == :array
|
117
|
+
@stream_writer.push_array
|
118
|
+
end
|
119
|
+
|
120
|
+
yield
|
121
|
+
|
122
|
+
@stream_writer.pop_all
|
123
|
+
@stream_writer.flush
|
124
|
+
result = output.string.sub(/\A,/, ''.freeze).chomp(",".freeze).strip
|
125
|
+
|
126
|
+
# Strip brackets as promised above
|
127
|
+
if @stack.last == :map
|
128
|
+
result = result.sub(/\A{/, ''.freeze).chomp("}".freeze)
|
129
|
+
elsif @stack.last == :array
|
130
|
+
result = result.sub(/\A\[/, ''.freeze).chomp("]".freeze)
|
131
|
+
end
|
132
|
+
|
133
|
+
result
|
134
|
+
ensure
|
135
|
+
@indexes.pop
|
136
|
+
@stream_writer = old_writer
|
137
|
+
@output = old_output
|
138
|
+
end
|
139
|
+
|
140
|
+
def flush
|
141
|
+
@stream_writer.flush
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
@@ -2,81 +2,82 @@ require 'wankel'
|
|
2
2
|
|
3
3
|
class TurboStreamer
|
4
4
|
class WankelEncoder < ::Wankel::StreamEncoder
|
5
|
-
|
5
|
+
|
6
6
|
def initialize(io, options={})
|
7
7
|
@stack = []
|
8
8
|
@indexes = []
|
9
|
-
|
9
|
+
|
10
10
|
super(io, {mode: :as_json}.merge(options))
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def key(k)
|
14
14
|
string(k)
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def value(v)
|
18
18
|
if @stack.last == :array || @stack.last == :map
|
19
19
|
@indexes[-1] += 1
|
20
20
|
end
|
21
21
|
super
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def map_open
|
25
25
|
@stack << :map
|
26
26
|
@indexes << 0
|
27
27
|
super
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def map_close
|
31
31
|
@indexes.pop
|
32
32
|
@stack.pop
|
33
33
|
super
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def array_open
|
37
37
|
@stack << :array
|
38
38
|
@indexes << 0
|
39
39
|
super
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def array_close
|
43
43
|
@indexes.pop
|
44
44
|
@stack.pop
|
45
45
|
super
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def inject(string)
|
49
49
|
flush
|
50
50
|
|
51
51
|
if @stack.last == :array
|
52
|
-
self.output.write(',') if @indexes.last > 0
|
52
|
+
self.output.write(','.freeze) if @indexes.last > 0
|
53
53
|
@indexes[-1] += 1
|
54
54
|
elsif @stack.last == :map
|
55
|
-
self.output.write(',') if @indexes.last > 0
|
55
|
+
self.output.write(','.freeze) if @indexes.last > 0
|
56
56
|
capture do
|
57
|
-
string("")
|
58
|
-
string("")
|
57
|
+
string("".freeze)
|
58
|
+
string("".freeze)
|
59
59
|
end
|
60
60
|
@indexes[-1] += 1
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
self.output.write(string)
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def capture(to=nil)
|
67
67
|
flush
|
68
|
-
|
68
|
+
old_output = self.output
|
69
|
+
to = to || ::StringIO.new
|
69
70
|
@indexes << 0
|
70
71
|
self.output = to
|
71
|
-
|
72
|
+
|
72
73
|
yield
|
73
|
-
|
74
|
+
|
74
75
|
flush
|
75
|
-
to.string.
|
76
|
+
to.string.sub(/\A,/, ''.freeze).chomp(",".freeze)
|
76
77
|
ensure
|
77
78
|
@indexes.pop
|
78
|
-
self.output =
|
79
|
+
self.output = old_output
|
79
80
|
end
|
80
|
-
|
81
|
+
|
81
82
|
end
|
82
|
-
end
|
83
|
+
end
|
@@ -1,3 +1,3 @@
|
|
1
1
|
class TurboStreamer
|
2
|
-
VERSION = '1.0'
|
3
|
-
end
|
2
|
+
VERSION = '1.1.0'
|
3
|
+
end
|
data/lib/turbostreamer.rb
CHANGED
@@ -2,49 +2,56 @@ require 'stringio'
|
|
2
2
|
require 'turbostreamer/key_formatter'
|
3
3
|
|
4
4
|
class TurboStreamer
|
5
|
-
|
5
|
+
|
6
6
|
BLANK = ::Object.new
|
7
|
-
|
8
|
-
|
7
|
+
|
8
|
+
|
9
9
|
ENCODERS = {
|
10
10
|
json: {oj: 'Oj', wankel: 'Wankel'},
|
11
11
|
msgpack: {msgpack: 'MessagePack'}
|
12
12
|
}
|
13
|
-
|
13
|
+
|
14
14
|
@@default_encoders = {}
|
15
15
|
@@key_formatter = nil
|
16
16
|
|
17
17
|
undef_method :==
|
18
18
|
undef_method :equal?
|
19
|
-
|
19
|
+
|
20
20
|
def self.encode(options = {}, &block)
|
21
21
|
new(options, &block).target!
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def initialize(options = {})
|
25
25
|
@output_buffer = options[:output_buffer] || ::StringIO.new
|
26
|
-
@encoder = options[:encoder]
|
26
|
+
@encoder = if options[:encoder].is_a?(Symbol)
|
27
|
+
TurboStreamer.get_encoder(options[:mime] || :json, options[:encoder])
|
28
|
+
elsif options[:encoder].nil?
|
29
|
+
TurboStreamer.default_encoder_for(options[:mime] || :json)
|
30
|
+
else
|
31
|
+
options[:encoder]
|
32
|
+
end
|
33
|
+
@encoder = @encoder.new(@output_buffer)
|
27
34
|
|
28
35
|
@key_formatter = options.fetch(:key_formatter){ @@key_formatter ? @@key_formatter.clone : nil }
|
29
36
|
|
30
37
|
yield self if ::Kernel.block_given?
|
31
38
|
end
|
32
|
-
|
39
|
+
|
33
40
|
def key!(key)
|
34
41
|
@encoder.key(_key(key))
|
35
42
|
end
|
36
|
-
|
43
|
+
|
37
44
|
def value!(value)
|
38
45
|
@encoder.value(value)
|
39
46
|
end
|
40
|
-
|
47
|
+
|
41
48
|
def object!(&block)
|
42
49
|
@encoder.map_open
|
43
50
|
_scope { block.call } if block
|
44
51
|
@encoder.map_close
|
45
52
|
end
|
46
|
-
|
47
|
-
# Extracts the mentioned attributes or hash elements from the passed object
|
53
|
+
|
54
|
+
# Extracts the mentioned attributes or hash elements from the passed object
|
48
55
|
# and turns them into a JSON object.
|
49
56
|
#
|
50
57
|
# Example:
|
@@ -63,8 +70,8 @@ class TurboStreamer
|
|
63
70
|
extract!(object, *attributes)
|
64
71
|
end
|
65
72
|
end
|
66
|
-
|
67
|
-
# Extracts the mentioned attributes or hash elements from the passed object
|
73
|
+
|
74
|
+
# Extracts the mentioned attributes or hash elements from the passed object
|
68
75
|
# and turns them into attributes of the JSON.
|
69
76
|
#
|
70
77
|
# Example:
|
@@ -85,7 +92,7 @@ class TurboStreamer
|
|
85
92
|
attributes.each{ |key| _set_value key, object.public_send(key) }
|
86
93
|
end
|
87
94
|
end
|
88
|
-
|
95
|
+
|
89
96
|
# Turns the current element into an array and iterates over the passed
|
90
97
|
# collection, adding each iteration as an element of the resulting array.
|
91
98
|
#
|
@@ -98,7 +105,7 @@ class TurboStreamer
|
|
98
105
|
#
|
99
106
|
# [ { "name": David", "age": 32 }, { "name": Jamie", "age": 31 } ]
|
100
107
|
#
|
101
|
-
# It's generally only needed to use this method for top-level arrays. If you
|
108
|
+
# It's generally only needed to use this method for top-level arrays. If you
|
102
109
|
# have named arrays, you can do:
|
103
110
|
#
|
104
111
|
# json.people(@people) do |person|
|
@@ -115,7 +122,7 @@ class TurboStreamer
|
|
115
122
|
# [1,2,3]
|
116
123
|
def array!(collection = BLANK, *attributes, &block)
|
117
124
|
@encoder.array_open
|
118
|
-
|
125
|
+
|
119
126
|
if _blank?(collection)
|
120
127
|
_scope(&block) if block
|
121
128
|
else
|
@@ -124,10 +131,10 @@ class TurboStreamer
|
|
124
131
|
|
125
132
|
@encoder.array_close
|
126
133
|
end
|
127
|
-
|
134
|
+
|
128
135
|
def set!(key, value = BLANK, *args, &block)
|
129
136
|
key!(key)
|
130
|
-
|
137
|
+
|
131
138
|
if block
|
132
139
|
if !_blank?(value)
|
133
140
|
# json.comments @post.comments { |comment| ... }
|
@@ -197,16 +204,20 @@ class TurboStreamer
|
|
197
204
|
def self.key_formatter=(formatter)
|
198
205
|
@@key_formatter = formatter
|
199
206
|
end
|
200
|
-
|
207
|
+
|
201
208
|
def self.set_default_encoder(mime, encoder)
|
202
|
-
|
209
|
+
if encoder.is_a?(Symbol)
|
210
|
+
@@default_encoders[mime] = get_encoder(mime, encoder)
|
211
|
+
else
|
212
|
+
@@default_encoders[mime] = encoder
|
213
|
+
end
|
203
214
|
end
|
204
|
-
|
215
|
+
|
205
216
|
def self.get_encoder(mime, key)
|
206
217
|
require "turbostreamer/encoders/#{key}"
|
207
218
|
Object.const_get("TurboStreamer::#{ENCODERS[mime][key]}Encoder")
|
208
219
|
end
|
209
|
-
|
220
|
+
|
210
221
|
def self.default_encoder_for(mime)
|
211
222
|
if @@default_encoders[mime]
|
212
223
|
@@default_encoders[mime]
|
@@ -215,7 +226,7 @@ class TurboStreamer
|
|
215
226
|
next if !const_defined?(class_name)
|
216
227
|
return get_encoder(mime, key)
|
217
228
|
end
|
218
|
-
|
229
|
+
|
219
230
|
ENCODERS[mime].to_a.find do |key, class_name|
|
220
231
|
begin
|
221
232
|
return get_encoder(mime, key)
|
@@ -223,7 +234,7 @@ class TurboStreamer
|
|
223
234
|
next
|
224
235
|
end
|
225
236
|
end
|
226
|
-
|
237
|
+
|
227
238
|
raise ArgumentError, "Could not find an adapter to use"
|
228
239
|
end
|
229
240
|
end
|
@@ -280,9 +291,9 @@ class TurboStreamer
|
|
280
291
|
else
|
281
292
|
object!{ extract!(value, *args) }
|
282
293
|
end
|
283
|
-
|
294
|
+
|
284
295
|
end
|
285
|
-
|
296
|
+
|
286
297
|
# Encodes the current builder as JSON.
|
287
298
|
def target!
|
288
299
|
@encoder.flush
|
@@ -293,9 +304,9 @@ class TurboStreamer
|
|
293
304
|
@encoder.output
|
294
305
|
end
|
295
306
|
end
|
296
|
-
|
307
|
+
|
297
308
|
private
|
298
|
-
|
309
|
+
|
299
310
|
def _write(key, value)
|
300
311
|
@encoder.key(_key(key))
|
301
312
|
@encoder.value(value)
|
@@ -313,7 +324,7 @@ class TurboStreamer
|
|
313
324
|
def _capture(to=nil, &block)
|
314
325
|
@encoder.capture(to, &block)
|
315
326
|
end
|
316
|
-
|
327
|
+
|
317
328
|
def _scope
|
318
329
|
parent_formatter = @key_formatter
|
319
330
|
yield
|
@@ -328,8 +339,8 @@ class TurboStreamer
|
|
328
339
|
def _blank?(value=@attributes)
|
329
340
|
BLANK == value
|
330
341
|
end
|
331
|
-
|
342
|
+
|
332
343
|
end
|
333
344
|
|
334
345
|
|
335
|
-
require 'turbostreamer/railtie' if defined?(Rails)
|
346
|
+
require 'turbostreamer/railtie' if defined?(Rails)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbostreamer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Bracy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: oj
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: bundler
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,6 +156,34 @@ dependencies:
|
|
142
156
|
- - ">="
|
143
157
|
- !ruby/object:Gem::Version
|
144
158
|
version: '0'
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: analyzer
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
- !ruby/object:Gem::Dependency
|
174
|
+
name: jbuilder
|
175
|
+
requirement: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
type: :development
|
181
|
+
prerelease: false
|
182
|
+
version_requirements: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
145
187
|
description:
|
146
188
|
email:
|
147
189
|
- jonbracy@gmail.com
|
@@ -155,6 +197,7 @@ files:
|
|
155
197
|
- ext/actionview/streaming_template_renderer.rb
|
156
198
|
- lib/turbostreamer.rb
|
157
199
|
- lib/turbostreamer/dependency_tracker.rb
|
200
|
+
- lib/turbostreamer/encoders/oj.rb
|
158
201
|
- lib/turbostreamer/encoders/wankel.rb
|
159
202
|
- lib/turbostreamer/handler.rb
|
160
203
|
- lib/turbostreamer/key_formatter.rb
|