mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-09 08:47:11 -05:00
79 lines
1.9 KiB
Ruby
79 lines
1.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Streaming JSON handler relays sections and streamed values back to the importer instance.
|
|
|
|
class JsonStreamHandler < Oj::Saj
|
|
HashState = Struct.new(:hash, :root, :key)
|
|
ArrayState = Struct.new(:array, :key)
|
|
StreamState = Struct.new(:key)
|
|
|
|
def initialize(processor)
|
|
super()
|
|
@processor = processor
|
|
@stack = []
|
|
end
|
|
|
|
def hash_start(key = nil, *_)
|
|
state = HashState.new({}, @stack.empty?, normalize_key(key))
|
|
@stack << state
|
|
end
|
|
|
|
def hash_end(key = nil, *_)
|
|
state = @stack.pop
|
|
value = state.hash
|
|
parent = @stack.last
|
|
|
|
dispatch_to_parent(parent, value, normalize_key(key) || state.key)
|
|
end
|
|
|
|
def array_start(key = nil, *_)
|
|
normalized_key = normalize_key(key)
|
|
parent = @stack.last
|
|
|
|
if parent.is_a?(HashState) && parent.root && @stack.size == 1 && Users::ImportData::STREAMED_SECTIONS.include?(normalized_key)
|
|
@stack << StreamState.new(normalized_key)
|
|
else
|
|
@stack << ArrayState.new([], normalized_key)
|
|
end
|
|
end
|
|
|
|
def array_end(key = nil, *_)
|
|
state = @stack.pop
|
|
case state
|
|
when StreamState
|
|
@processor.send(:finish_stream, state.key)
|
|
when ArrayState
|
|
value = state.array
|
|
parent = @stack.last
|
|
dispatch_to_parent(parent, value, normalize_key(key) || state.key)
|
|
end
|
|
end
|
|
|
|
def add_value(value, key)
|
|
parent = @stack.last
|
|
dispatch_to_parent(parent, value, normalize_key(key))
|
|
end
|
|
|
|
private
|
|
|
|
def normalize_key(key)
|
|
key&.to_s
|
|
end
|
|
|
|
def dispatch_to_parent(parent, value, key)
|
|
return unless parent
|
|
|
|
case parent
|
|
when HashState
|
|
if parent.root && @stack.size == 1
|
|
@processor.send(:handle_section, key, value)
|
|
else
|
|
parent.hash[key] = value
|
|
end
|
|
when ArrayState
|
|
parent.array << value
|
|
when StreamState
|
|
@processor.send(:handle_stream_value, parent.key, value)
|
|
end
|
|
end
|
|
end
|