Class: Janeway::Enumerator

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/janeway/enumerator.rb

Overview

Enumerator combines a JSONPath query with input. It provides methods for running queries on the input and enumerating over the results.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(query, input) ⇒ Enumerator

Returns a new instance of Enumerator.

Parameters:

Raises:

  • (ArgumentError)


16
17
18
19
20
21
# File 'lib/janeway/enumerator.rb', line 16

def initialize(query, input)
  @query = query
  @input = input

  raise ArgumentError, "expect Janeway::Query, got #{query.inspect}" unless query.is_a?(Query)
end

Instance Attribute Details

#queryJaneway::Query (readonly)

Returns:



12
13
14
# File 'lib/janeway/enumerator.rb', line 12

def query
  @query
end

Instance Method Details

#deleteArray

Delete values from the input that are matched by the JSONPath query.

Returns:

  • (Array)

    deleted values



45
46
47
# File 'lib/janeway/enumerator.rb', line 45

def delete
  Janeway::Interpreter.new(@query, as: :deleter).interpret(@input)
end

#delete_if(&block) ⇒ Array

Delete values from the input that are matched by the JSONPath query and also return a truthy value from the block.

Returns:

  • (Array)

    deleted values



52
53
54
# File 'lib/janeway/enumerator.rb', line 52

def delete_if(&block)
  Janeway::Interpreter.new(@query, as: :delete_if, &block).interpret(@input)
end

#each {|value, parent, hash, normalized| ... } ⇒ void

This method returns an undefined value.

Iterate through each value matched by the JSONPath query.

Yield Parameters:

  • value (Object)

    matched by query

  • parent (Array, Hash)

    object that contains the value

  • hash (String, Integer)

    key or array index of the value within the parent object

  • normalized (String)

    jsonpath that uniqely points to this value



37
38
39
40
41
# File 'lib/janeway/enumerator.rb', line 37

def each(&block)
  return enum_for(:each) unless block_given?

  Janeway::Interpreter.new(@query, as: :iterator, &block).interpret(@input)
end

#insert(value) {|parent, array| ... } ⇒ Object

Insert ‘value` into the input at a location specified by a singular query.

This has restrictions:

* Only for singular queries
  (no wildcards, filter expressions, child segments, etc.)
* The "parent" node must exist
  eg. for $.a[1].name, the path $.a[1] must exist and be a Hash
* Cannot create array index N unless the array
  already has exactly N-1 elements
* If query path already exists, the block is called if provided.
  Otherwise an exception is raised.

Optionally, pass in a block to be called when there is already a value at the specified array index / hash key. The parent object and the array index or hash key will be yielded to the block.

Yield Parameters:

  • parent (Array, Hash)

    object

  • array (Intgeer, String)

    index or hash key



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/janeway/enumerator.rb', line 102

def insert(value, &block)
  # Query must point to a single target object
  unless @query.singular_query?
    msg = 'Janeway::Query#insert may only be used with a singular query'
    raise Janeway::Error.new(msg, @query)
  end

  # Find parent of new value
  parent, key, parent_path = find_parent

  # Insert new value into parent
  case parent
  when Hash then insert_into_hash(parent, key, value, parent_path, &block)
  when Array then insert_into_array(parent, key, value, parent_path, &block)
  else
    raise Error.new("cannot insert into basic type: #{parent.inspect}", @query.to_s)
  end
end

#replace(replacement = :no_replacement_value_was_given, &block) ⇒ void

This method returns an undefined value.

Assign the given value at every query match.

Parameters:

  • replacement (Object) (defaults to: :no_replacement_value_was_given)


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/janeway/enumerator.rb', line 59

def replace(replacement = :no_replacement_value_was_given, &block)
  if replacement != :no_replacement_value_was_given && block_given?
    raise Janeway::Error.new('#replace needs either replacement value or block, not both', @query)
  end

  # Avoid infinite loop when the replacement data would also be matched by the query
  previous = []
  each do |_, parent, key|
    # Update the previous match
    unless previous.empty?
      prev_parent, prev_key = *previous
      prev_parent[prev_key] = block_given? ? yield(prev_parent[prev_key]) : replacement
    end

    # Record this match to be updated later
    previous = [parent, key]
  end
  return if previous.empty?

  # Update the final match
  prev_parent, prev_key = *previous
  prev_parent[prev_key] = block_given? ? yield(prev_parent[prev_key]) : replacement
  nil
end

#searchArray

Return a list of values from the input data that match the jsonpath query

Returns:

  • (Array)

    all matched objects



26
27
28
# File 'lib/janeway/enumerator.rb', line 26

def search
  Janeway::Interpreter.new(@query).interpret(@input)
end