Class: JsonDataExtractor::Extractor

Inherits:
Object
  • Object
show all
Defined in:
lib/json_data_extractor/extractor.rb

Overview

does the main job of the gem

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(json_data, modifiers = {}) ⇒ Extractor

Returns a new instance of Extractor.

Parameters:

  • json_data (Hash, String)
  • modifiers (Hash) (defaults to: {})


10
11
12
13
14
15
# File 'lib/json_data_extractor/extractor.rb', line 10

def initialize(json_data, modifiers = {})
  @data = json_data.is_a?(Hash) ? Oj.dump(json_data, mode: :compat) : json_data
  @modifiers = modifiers.transform_keys(&:to_sym)
  @results = {}
  @path_cache = {}
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



6
7
8
# File 'lib/json_data_extractor/extractor.rb', line 6

def data
  @data
end

#modifiersObject (readonly)

Returns the value of attribute modifiers.



6
7
8
# File 'lib/json_data_extractor/extractor.rb', line 6

def modifiers
  @modifiers
end

Instance Method Details

#add_modifier(modifier_name, callable = nil, &block) ⇒ Object

Parameters:

  • modifier_name (String, Symbol)
  • callable (#call, nil) (defaults to: nil)

    Optional callable object

Raises:

  • (ArgumentError)


19
20
21
22
23
24
25
26
# File 'lib/json_data_extractor/extractor.rb', line 19

def add_modifier(modifier_name, callable = nil, &block)
  modifier_name = modifier_name.to_sym unless modifier_name.is_a?(Symbol)
  modifiers[modifier_name] = callable || block

  return if modifiers[modifier_name].respond_to?(:call)

  raise ArgumentError, 'Modifier must be a callable object or a block'
end

#extract(schema) ⇒ Object

Parameters:

  • schema (Hash)

    schema of the expected data mapping



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/json_data_extractor/extractor.rb', line 29

def extract(schema)
  schema.each do |key, val|
    element = JsonDataExtractor::SchemaElement.new(val.is_a?(Hash) ? val : { path: val })

    path = element.path
    json_path = path ? (@path_cache[path] ||= JsonPath.new(path)) : nil

    extracted_data = json_path&.on(@data)

    if extracted_data.nil? || extracted_data.empty?
      # we either got nothing or the `path` was initially nil
      @results[key] = element.fetch_default_value
      next
    end

    # check for nils and apply defaults if applicable
    extracted_data.map! { |item| item.nil? ? element.fetch_default_value : item }

    # apply modifiers if present
    extracted_data = apply_modifiers(extracted_data, element.modifiers) if element.modifiers.any?

    # apply maps if present
    @results[key] = element.maps.any? ? apply_maps(extracted_data, element.maps) : extracted_data

    @results[key] = resolve_result_structure(@results[key], element)
  end

  @results
end