lib/json/streamer/json_streamer.rb in json-streamer-1.3.0 vs lib/json/streamer/json_streamer.rb in json-streamer-2.0.0
- old
+ new
@@ -1,144 +1,58 @@
require "json/stream"
+require_relative 'conditions'
+require_relative 'parser'
+
module Json
module Streamer
class JsonStreamer
- attr_reader :aggregator
attr_reader :parser
def initialize(file_io = nil, chunk_size = 1000)
- @parser = JSON::Stream::Parser.new
+ @event_generator = JSON::Stream::Parser.new
@file_io = file_io
@chunk_size = chunk_size
-
- @current_level = -1
- @aggregator = {}
- @aggregator_keys = {}
-
- @parser.start_object {start_object}
- @parser.start_array {start_array}
- @parser.key {|k| key(k)}
end
def <<(data)
- @parser << data
+ parser << data
end
- # Callbacks containing `yield` have to be defined in the method called via block otherwise yield won't work
def get(nesting_level: -1, key: nil, yield_values: true, symbolize_keys: false)
- @yield_level = nesting_level
- @yield_key = key
- @yield_values = yield_values
- @symbolize_keys = symbolize_keys
+ conditions = Conditions.new(yield_level: nesting_level, yield_key: key)
+ conditions.yield_value = ->(aggregator:, value:) { false } unless yield_values
- @parser.value do |v|
- value(v) { |desired_object| yield desired_object }
- end
+ # TODO: deprecate symbolize_keys and move to initialize
+ @parser = Parser.new(@event_generator, symbolize_keys: symbolize_keys)
- @parser.end_object do
- end_level(Hash.new) { |desired_object| yield desired_object }
+ parser.get(conditions) do |obj|
+ yield obj
end
- @parser.end_array do
- end_level(Array.new) { |desired_object| yield desired_object }
- end
-
- @file_io.each(@chunk_size) { |chunk| @parser << chunk } if @file_io
+ process_io
end
- def start_object
- new_level(Hash.new)
- end
+ def get_with_conditions(conditions, options = {})
+ @parser = Parser.new(@event_generator, symbolize_keys: options[:symbolize_keys])
- def start_array
- new_level(Array.new)
- end
-
- def key(k)
- @current_key = @symbolize_keys ? k.to_sym : k
- end
-
- def value(value)
- reset_current_key if array_level?(@current_level)
- yield value if yield_value?
- add_value(value)
- end
-
- def add_value(value)
- if array_level?(@current_level)
- @aggregator[@current_level] << value
- else
- @aggregator[@current_level][@current_key] = value
+ parser.get(conditions) do |obj|
+ yield obj
end
- end
- def end_level(type)
- if yield_object?
- yield @aggregator[@current_level].clone
- reset_current_level(type)
- else
- merge_up
- end
-
- @current_level -= 1
+ process_io
end
- def yield_object?
- @current_level.eql?(@yield_level) or (not @yield_key.nil? and @yield_key == previous_key)
+ def aggregator
+ parser.aggregator
end
- def yield_value?
- @yield_values and ((next_level).eql?(@yield_level) or (not @yield_key.nil? and @yield_key == @current_key))
- end
+ private
- def new_level(type)
- reset_current_key if array_level?(@current_level)
- set_aggregator_key
- @current_level += 1
- reset_current_level(type)
- end
-
- def reset_current_level(type)
- @aggregator[@current_level] = type
- end
-
- def set_aggregator_key
- @aggregator_keys[@current_level] = @current_key
- end
-
- def reset_current_key
- @current_key = nil
- end
-
- def array_level?(nesting_level)
- @aggregator[nesting_level].is_a?(Array)
- end
-
- def merge_up
- return if @current_level.zero?
-
- if array_level?(previous_level)
- @aggregator[previous_level] << @aggregator[@current_level]
- else
- @aggregator[previous_level][previous_key] = @aggregator[@current_level]
- end
-
- @aggregator.delete(@current_level)
- end
-
- def previous_level
- @current_level - 1
- end
-
- def next_level
- @current_level + 1
- end
-
- def previous_key
- @aggregator_keys[previous_level]
+ def process_io
+ @file_io.each(@chunk_size) { |chunk| parser << chunk } if @file_io
end
end
end
end