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

Class Method 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

#schema_cacheObject (readonly)

Returns the value of attribute schema_cache.



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

def schema_cache
  @schema_cache
end

Class Method Details

.with_schema(schema, modifiers = {}) ⇒ Extractor

Creates a new extractor with a pre-processed schema

Parameters:

  • schema (Hash)

    schema of the expected data mapping

  • modifiers (Hash) (defaults to: {})

    modifiers to apply to the extracted data

Returns:

  • (Extractor)

    an extractor initialized with the schema



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

def self.with_schema(schema, modifiers = {})
  extractor = new({}, modifiers)
  extractor.instance_variable_set(:@schema_cache, SchemaCache.new(schema))
  extractor
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)


48
49
50
51
52
53
54
55
# File 'lib/json_data_extractor/extractor.rb', line 48

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



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/json_data_extractor/extractor.rb', line 58

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

#extract_from(json_data) ⇒ Hash

Extracts data from the provided json_data using the cached schema

Parameters:

  • json_data (Hash, String)

    the data to extract from

Returns:

  • (Hash)

    the extracted data

Raises:

  • (ArgumentError)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/json_data_extractor/extractor.rb', line 30

def extract_from(json_data)
  # Ensure we have a schema cache
  raise ArgumentError, 'No schema cache available. Use Extractor.with_schema first.' unless @schema_cache

  # Reset results
  @results = {}

  # Update data
  @data = json_data.is_a?(Hash) ? Oj.dump(json_data, mode: :compat) : json_data

  # Extract data using cached schema
  extract_using_cache

  @results
end