Class: Verquest::Transformer
- Inherits:
-
Object
- Object
- Verquest::Transformer
- Defined in:
- lib/verquest/transformer.rb
Overview
Transforms parameters based on path mappings
The Transformer class handles the conversion of parameter structures based on a mapping of source paths to target paths. It supports deep nested structures, array notations, and complex path expressions using dot notation.
Instance Attribute Summary collapse
-
#mapping ⇒ Hash
readonly
private
The source-to-target path mapping.
-
#path_cache ⇒ Object
readonly
private
Returns the value of attribute path_cache.
Instance Method Summary collapse
-
#call(params) ⇒ Hash
Transforms input parameters according to the provided mapping.
-
#extract_value(data, path_parts) ⇒ Object?
private
Extracts a value from nested data structure using the parsed path parts.
-
#initialize(mapping:) ⇒ Transformer
constructor
Creates a new Transformer with the specified mapping.
-
#parse_path(path) ⇒ Array<Hash>
private
Parses a dot-notation path into structured path parts Uses memoization for performance optimization.
-
#precompile_paths ⇒ void
private
Precompiles all paths from the mapping to improve performance This is called during initialization to prepare the cache.
-
#set_value(result, path_parts, value) ⇒ Hash
private
Sets a value in a result hash at the specified path.
Constructor Details
#initialize(mapping:) ⇒ Transformer
Creates a new Transformer with the specified mapping
43 44 45 46 47 |
# File 'lib/verquest/transformer.rb', line 43 def initialize(mapping:) @mapping = mapping @path_cache = {} # Cache for parsed paths to improve performance precompile_paths # Prepare cache during initialization end |
Instance Attribute Details
#mapping ⇒ Hash (readonly, private)
Returns The source-to-target path mapping.
74 75 76 |
# File 'lib/verquest/transformer.rb', line 74 def mapping @mapping end |
#path_cache ⇒ Object (readonly, private)
Returns the value of attribute path_cache.
74 |
# File 'lib/verquest/transformer.rb', line 74 attr_reader :mapping, :path_cache |
Instance Method Details
#call(params) ⇒ Hash
Transforms input parameters according to the provided mapping
53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/verquest/transformer.rb', line 53 def call(params) result = {} mapping.each do |source_path, target_path| # Extract value using the source path value = extract_value(params, parse_path(source_path.to_s)) next if value.nil? # Set the extracted value at the target path set_value(result, parse_path(target_path.to_s), value) end result end |
#extract_value(data, path_parts) ⇒ Object? (private)
Extracts a value from nested data structure using the parsed path parts
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/verquest/transformer.rb', line 107 def extract_value(data, path_parts) return data if path_parts.empty? current_part = path_parts.first remaining_path = path_parts[1..] key = current_part[:key] case data when Hash # Only check for string keys return nil unless data.key?(key.to_s) # Always use string keys value = data[key.to_s] if current_part[:array] && value.is_a?(Array) # Process array elements and filter out nil values value.map { |item| extract_value(item, remaining_path) }.compact else # Continue traversing the path extract_value(value, remaining_path) end when Array if current_part[:array] # Map through array elements with remaining path data.map { |item| extract_value(item, remaining_path) }.compact else # Try to extract from each array element with the full path result = data.map { |item| extract_value(item, path_parts) }.compact result.empty? ? nil : result end else # For scalar values, return only if we're at the end of the path remaining_path.empty? ? data : nil end end |
#parse_path(path) ⇒ Array<Hash> (private)
Parses a dot-notation path into structured path parts Uses memoization for performance optimization
92 93 94 95 96 97 98 99 100 |
# File 'lib/verquest/transformer.rb', line 92 def parse_path(path) path_cache[path] ||= path.split(".").map do |part| if part.end_with?("[]") {key: part[0...-2], array: true} else {key: part, array: false} end end end |
#precompile_paths ⇒ void (private)
This method returns an undefined value.
Precompiles all paths from the mapping to improve performance This is called during initialization to prepare the cache
80 81 82 83 84 85 |
# File 'lib/verquest/transformer.rb', line 80 def precompile_paths mapping.each do |source_path, target_path| parse_path(source_path.to_s) parse_path(target_path.to_s) end end |
#set_value(result, path_parts, value) ⇒ Hash (private)
Sets a value in a result hash at the specified path
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/verquest/transformer.rb', line 150 def set_value(result, path_parts, value) return result if path_parts.empty? current_part = path_parts.first remaining_path = path_parts[1..] key = current_part[:key].to_s # Ensure key is a string for consistency if remaining_path.empty? # End of path, set the value directly result[key] = value elsif current_part[:array] && value.is_a?(Array) # Handle array notation in target path result[key] ||= [] # Process each value in the array value.each_with_index do |v, i| result[key][i] ||= {} set_value(result[key][i], remaining_path, v) end else # Continue building nested structure result[key] ||= {} set_value(result[key], remaining_path, value) end result end |