Class: Rjq::Runtime

Inherits:
Object
  • Object
show all
Defined in:
lib/rjq/runtime.rb

Defined Under Namespace

Classes: InputQueue, InputRecord, ResultStream

Constant Summary collapse

DEFAULT_OPTIONS =
{
  compact: false, raw_output: false, raw_output0: false, join_output: false,
  null_input: false, raw_input: false, slurp: false, ascii: false,
  sort_keys: false, tab: false, indent: 2, seq: false, stream: false,
  stream_errors: false, unbuffered: false, max_call_depth: nil, max_instructions: nil,
  max_outputs: nil, variables: {}
}.freeze
OPTION_KEYS =
(DEFAULT_OPTIONS.keys + %i[
  allow_comments color current_filename current_line exit_status input_chunk_size input_max_depth input_queue
  jq_origin library_path max_filter_depth max_number_digits max_string_bytes module_resolver regexp_timeout
  max_replay_cache remaining_inputs runtime_error_handler source_path stderr
]).freeze
BOOLEAN_OPTIONS =
%i[
  allow_comments ascii compact exit_status join_output null_input raw_input raw_output raw_output0 seq slurp
  sort_keys stream stream_errors tab unbuffered
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filter_string, opts = {}) ⇒ Runtime

Returns a new instance of Runtime.



195
196
197
198
199
# File 'lib/rjq/runtime.rb', line 195

def initialize(filter_string, opts = {})
  @filter_string = filter_string || '.'
  @opts = self.class.normalize_options(DEFAULT_OPTIONS.merge(opts))
  @program = Rjq.compile(@filter_string, Compiler.options_from(@opts))
end

Class Method Details

.normalize_options(opts) ⇒ Object



49
50
51
52
53
54
55
# File 'lib/rjq/runtime.rb', line 49

def normalize_options(opts)
  validate_options!(opts)
  normalized = opts.dup
  normalized[:variables] = normalized[:variables].dup.freeze if normalized[:variables]
  normalized[:library_path] = normalized[:library_path].dup.freeze if normalized[:library_path]
  normalized.freeze
end

.validate_options!(opts) ⇒ Object

Raises:

  • (ArgumentError)


23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/rjq/runtime.rb', line 23

def validate_options!(opts)
  raise ArgumentError, 'options must be a Hash' unless opts.is_a?(Hash)

  unknown = opts.keys - OPTION_KEYS
  raise ArgumentError, "unknown runtime option: #{unknown.first.inspect}" unless unknown.empty?

  BOOLEAN_OPTIONS.each { |key| validate_boolean!(opts, key) }
  validate_color!(opts)
  validate_integer!(opts, :indent, minimum: 0, maximum: 7)
  validate_integer!(opts, :input_chunk_size, minimum: 1)
  validate_integer!(opts, :input_max_depth, minimum: 0)
  validate_integer!(opts, :max_call_depth, minimum: 1, optional: true)
  validate_integer!(opts, :max_instructions, minimum: 0, optional: true)
  validate_integer!(opts, :max_replay_cache, minimum: 0, optional: true)
  validate_integer!(opts, :current_line, minimum: 1, optional: true)
  validate_integer!(opts, :max_number_digits, minimum: 0, optional: true)
  validate_integer!(opts, :max_outputs, minimum: 0, optional: true)
  validate_integer!(opts, :max_string_bytes, minimum: 0, optional: true)
  validate_regexp_timeout!(opts)
  validate_stderr!(opts)
  validate_runtime_error_handler!(opts)
  validate_variables!(opts)
  Compiler.validate_options!(Compiler.options_from(opts))
  opts
end

Instance Method Details

#format_output(value) ⇒ Object



229
230
231
232
233
234
235
236
# File 'lib/rjq/runtime.rb', line 229

def format_output(value)
  return value if @opts[:raw_output] && value.is_a?(String)

  indent = @opts[:compact] ? nil : @opts[:indent]
  dumped = JSON::Dumper.dump(value, indent: indent, sort_keys: @opts[:sort_keys], ascii: @opts[:ascii],
                                    tab: @opts[:tab])
  @opts[:color] ? Color.colorize(dumped) : dumped
end

#run_io_streams(streams) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/rjq/runtime.rb', line 215

def run_io_streams(streams)
  owned_streams = []
  records = records_from_streams(streams, owned_streams)
  close_streams = lambda do
    owned_streams.each { |io| io.close unless io.closed? }
  end
  if @opts[:null_input]
    main = InputQueue.new([InputRecord.new(value: nil, filename: nil, line: 1)])
    return run_queue(main, InputQueue.new(records), on_close: close_streams)
  end

  run_queue(InputQueue.new(records), on_close: close_streams)
end

#run_stream(io, &block) ⇒ Object



208
209
210
211
212
213
# File 'lib/rjq/runtime.rb', line 208

def run_stream(io, &block)
  enum = run_io_streams([[io, nil, false]])
  return enum unless block

  enum.each(&block)
end

#run_values(values, input_queue: nil) ⇒ Object



201
202
203
204
205
206
# File 'lib/rjq/runtime.rb', line 201

def run_values(values, input_queue: nil)
  records = values.lazy.map { |value| InputRecord.new(value: value, filename: nil, line: 1) }
  queue = InputQueue.new(records)
  builtin_queue = input_queue.is_a?(InputQueue) ? input_queue : queue
  run_queue(queue, builtin_queue)
end

#write_output(value, io) ⇒ Object



238
239
240
241
242
243
244
245
246
247
248
# File 'lib/rjq/runtime.rb', line 238

def write_output(value, io)
  if @opts[:raw_output] && value.is_a?(String)
    io << value
  elsif @opts[:color]
    io << format_output(value)
  else
    indent = @opts[:compact] ? nil : @opts[:indent]
    JSON::Dumper.dump(value, indent: indent, sort_keys: @opts[:sort_keys], ascii: @opts[:ascii],
                            tab: @opts[:tab], io: io)
  end
end