Class: DryStructParser::StructSchemaParser

Inherits:
Object
  • Object
show all
Defined in:
lib/dry_struct_parser/struct_schema_parser.rb

Constant Summary collapse

PREDICATE_TYPES =
{
  String: "string",
  Integer: "integer",
  TrueClass: "boolean",
  FalseClass: "boolean",
  Float: "float",
  BigDecimal: "decimal",
  Date: "date",
  DateTime: "datetime",
  Time: "time"
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStructSchemaParser

Returns a new instance of StructSchemaParser.



19
20
21
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 19

def initialize
  @keys = {}
end

Instance Attribute Details

#keysObject (readonly)

Returns the value of attribute keys.



17
18
19
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 17

def keys
  @keys
end

Instance Method Details

#call(struct, &block) ⇒ Object



27
28
29
30
31
32
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 27

def call(struct, &block)
  @keys = {}
  visit(struct.schema.to_ast)
  instance_eval(&block) if block_given?
  self
end

#to_hObject



23
24
25
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 23

def to_h
  { keys: keys }
end

#visit(node, opts = {}) ⇒ Object



34
35
36
37
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 34

def visit(node, opts = {})
  meth, rest = node
  public_send(:"visit_#{meth}", rest, opts)
end

#visit_and(node, opts = {}) ⇒ Object



100
101
102
103
104
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 100

def visit_and(node, opts = {})
  left, right = node
  visit(left, opts)
  visit(right, opts)
end

#visit_array(node, opts = {}) ⇒ Object



125
126
127
128
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 125

def visit_array(node, opts = {})
  opts[:array] = true
  visit(node[0], opts)
end

#visit_constrained(node, opts = {}) ⇒ Object



74
75
76
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 74

def visit_constrained(node, opts = {})
  node.each { |it| visit(it, opts) }
end

#visit_constructor(node, opts = {}) ⇒ Object



39
40
41
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 39

def visit_constructor(node, opts = {})
  visit(node[0], opts)
end

#visit_enum(node, opts = {}) ⇒ Object



106
107
108
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 106

def visit_enum(node, opts = {})
  visit(node[0], opts)
end

#visit_key(node, opts = {}) ⇒ Object



67
68
69
70
71
72
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 67

def visit_key(node, opts = {})
  name, required, rest = node
  opts[:key] = name
  opts[:required] = required
  visit(rest, opts)
end

#visit_nominal(_node, _opts) ⇒ Object



78
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 78

def visit_nominal(_node, _opts); end

#visit_predicate(node, opts = {}) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 80

def visit_predicate(node, opts = {})
  name, rest = node
  type = rest[0][1]
  if name.equal?(:type?)
    type = type.to_s.to_sym
    return unless PREDICATE_TYPES[type]

    type_definition = {
      type: PREDICATE_TYPES[type],
      required: opts.fetch(:required),
      nullable: opts.fetch(:nullable, false)
    }
    type_definition[:array] = opts[:array] if opts[:array]
    keys[opts[:key]] = type_definition
  elsif name.equal?(:included_in?)
    type += [nil] if opts.fetch(:nullable, false)
    keys[opts[:key]][:enum] = type
  end
end

#visit_schema(node, opts = {}) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 43

def visit_schema(node, opts = {})
  target = (key = opts[:key]) ? self.class.new : self
  required = opts.fetch(:required, true)
  nullable = opts.fetch(:nullable, false)
  node[0].each { |child| target.visit(child) }
  return unless key

  target_info = target.to_h if opts[:member]
  type = opts[:array] ? "array" : "hash"
  definition = {
    type: type,
    required: required,
    nullable: nullable,
    **target_info
  }
  if opts[:oneOf]
    keys[key] ? keys[key] << definition : keys[key] = [definition]
  else
    keys[key] = definition
  end

  keys[key]
end

#visit_struct(node, opts = {}) ⇒ Object



120
121
122
123
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 120

def visit_struct(node, opts = {})
  opts[:member] = true
  visit(node[1], opts)
end

#visit_sum(node, opts = {}) ⇒ Object



110
111
112
113
114
115
116
117
118
# File 'lib/dry_struct_parser/struct_schema_parser.rb', line 110

def visit_sum(node, opts = {})
  if node[0][0].equal?(:constrained)
    opts[:nullable] = true if node[0][1][0][1][0].equal?(NilClass)
    visit(node[1], opts) # ignore NilClass constrained
  elsif node[0][0].equal?(:struct) || node[0][0].equal?(:sum)
    opts[:oneOf] = true
    node.each { |child| visit(child, opts) unless child.is_a?(Hash) }
  end
end