Class: Paradocs::Extensions::Structure

Inherits:
Object
  • Object
show all
Defined in:
lib/paradocs/extensions/structure.rb

Constant Summary collapse

DEFAULT =
:generic

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(schema, ignore_transparent = true, root = "") ⇒ Structure

Returns a new instance of Structure.



11
12
13
14
15
# File 'lib/paradocs/extensions/structure.rb', line 11

def initialize(schema, ignore_transparent=true, root="")
  @schema             = schema
  @ignore_transparent = ignore_transparent
  @root               = root
end

Instance Attribute Details

#ignore_transparentObject

Returns the value of attribute ignore_transparent.



9
10
11
# File 'lib/paradocs/extensions/structure.rb', line 9

def ignore_transparent
  @ignore_transparent
end

#rootObject (readonly)

Returns the value of attribute root.



9
10
11
# File 'lib/paradocs/extensions/structure.rb', line 9

def root
  @root
end

#schemaObject (readonly)

Returns the value of attribute schema.



9
10
11
# File 'lib/paradocs/extensions/structure.rb', line 9

def schema
  @schema
end

Instance Method Details

#all_flatten(schema_structure = nil, &block) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/paradocs/extensions/structure.rb', line 61

def all_flatten(schema_structure=nil, &block)
  schema_structure ||= flatten(&block)
  if schema_structure[subschemes].empty?
    schema_structure.delete(subschemes) # don't include redundant key
    return {DEFAULT => schema_structure}
  end
  schema_structure[subschemes].each_with_object({}) do |(name, subschema), result|
    if subschema[subschemes].empty?
      result[name] = schema_structure.merge(subschema)
      result[name][errors] += schema_structure[errors]
      result[name][errors].uniq!
      result[name].delete(subschemes)
      next result[name]
    end

    all_flatten(subschema).each do |sub_name, schema|
      result["#{name}_#{sub_name}".to_sym] = schema_structure.merge(schema)
    end
  end
end

#all_nested(&block) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/paradocs/extensions/structure.rb', line 39

def all_nested(&block)
  all_flatten(&block).each_with_object({}) do |(name, struct), obj|
    obj[name] = {}
    # sort the flatten struct to have iterated 1lvl keys before 2lvl and so on...
    struct.sort_by { |k, v| k.to_s.count(".") }.each do |key, value|
      target = obj[name]
      key, value = key.to_s, value.clone # clone the values, because we do mutation below
      value.merge!(nested_name: key) if value.respond_to?(:merge) # it can be array (_errors)
      next target[key.to_sym] = value if key.start_with?(Paradocs.config.meta_prefix) # copy meta fields

      parts = key.split(".")
      next target[key] ||= value if parts.size == 1 # copy 1lvl key
      parts.each.with_index do |subkey, index|
        target[subkey] ||= value
        next if parts.size == index + 1
        target[subkey][:structure] ||= {}
        target = target[subkey][:structure] # target goes deeper for each part
      end
    end
  end
end

#flatten(&block) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/paradocs/extensions/structure.rb', line 82

def flatten(&block)
  schema.fields.each_with_object({errors => [], subschemes => {}}) do |(_, field), obj|
    meta, sc = collect_meta(field, root)
    humanized_name = meta.delete(:nested_name)
    obj[humanized_name] = meta unless ignore_transparent && field.transparent?

    if sc
      deep_result = self.class.new(sc, ignore_transparent, meta[:json_path]).flatten(&block)
      obj[errors] += deep_result.delete(errors)
      obj[subschemes].merge!(deep_result.delete(subschemes))
      obj.merge!(deep_result)
    else
      obj[errors] += field.possible_errors
    end
    yield(humanized_name, meta) if block_given?
    next unless field.mutates_schema?
    schema.subschemes.each do |name, subschema|
      obj[subschemes][name] ||= self.class.new(subschema, ignore_transparent, root).flatten(&block)
      obj[errors] += obj[subschemes][name][errors]
    end
  end
end

#nested(&block) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/paradocs/extensions/structure.rb', line 17

def nested(&block)
  schema.fields.each_with_object({errors => [], subschemes => {}}) do |(_, field), result|
    meta, sc = collect_meta(field, root)
    if sc
      meta[:structure] = self.class.new(sc, ignore_transparent, meta[:json_path]).nested(&block)
      result[errors] += meta[:structure].delete(errors)
    else
      result[errors] += field.possible_errors
    end

    field_key = field.[:alias] || field.key
    result[field_key] = meta unless ignore_transparent && field.transparent?
    yield(field_key, meta) if block_given?

    next unless field.mutates_schema?
    schema.subschemes.each do |name, subschema|
      result[subschemes][name] = self.class.new(subschema, ignore_transparent, root).nested(&block)
      result[errors] += result[subschemes][name][errors]
    end
  end
end