15
16
17
18
19
20
21
22
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
48
49
50
51
52
|
# File 'lib/appmap/value_inspector.rb', line 15
def detect_schema(
value,
max_depth: MAX_DEPTH,
max_array_elements: MAX_ARRAY_ELEMENTS,
type_info: { class: best_class_name(value) },
observed_values: Set.new,
depth: 0
)
return type_info if depth >= max_depth && !array_like?(value)
if hash_like?(value)
return if observed_values.include?(value.object_id)
observed_values << value.object_id
properties = value.keys.select { |key| key != "" && !key.nil? }.map do |key|
next_value = value[key]
value_schema = begin
{ name: key, class: best_class_name(next_value) }
rescue
warn "Error in add_schema(#{next_value.class})", $!
raise
end
detect_schema(next_value, **{ max_depth: max_depth, type_info: value_schema, observed_values: observed_values, depth: depth + 1 })
end.compact
type_info[:properties] = properties unless properties.empty?
elsif array_like?(value)
type_info[:items] = value.take(max_array_elements).map do |next_value|
value_schema = { class: best_class_name(next_value) }
detect_schema(next_value, **{ max_depth: max_depth, type_info: value_schema, observed_values: observed_values, depth: depth + 1 })
end
type_info[:items] = type_info[:items].compact.uniq(&:hash)
end
type_info
end
|