Class: Respect::DslDumper

Inherits:
Object
  • Object
show all
Defined in:
lib/respect/dsl_dumper.rb

Overview

Dump a schema to a string representation using the DSL syntax so you can evaluate it and get the same schema back.

Theoretically, this must always be true:

eval(DslDumper.new(schema).dump) == schema

The current implementation covers all the Schema and Validator classes defined in this package. User-defined sub-class of Schema are not guarantee to work. Specially those using a custom "Def" class or with special attributes. The API of this dumper is experimental, so relying on it to teach the dumper how to dump a user-defined schema class may break in future releases.

However, sub-classes of CompositeSchema are handled properly as well as all Validator sub-classes.

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (DslDumper) initialize(schema)

A new instance of DslDumper



19
20
21
22
23
24
# File 'lib/respect/dsl_dumper.rb', line 19

def initialize(schema)
  @schema = schema
  @indent_level = 0
  @indent_size = 2
  @context_data = {}
end

Instance Attribute Details

- (Object) context_data

Returns the value of attribute context_data



60
61
62
# File 'lib/respect/dsl_dumper.rb', line 60

def context_data
  @context_data
end

- (Object) output (readonly)

Returns the value of attribute output



26
27
28
# File 'lib/respect/dsl_dumper.rb', line 26

def output
  @output
end

- (Object) schema (readonly)

Returns the value of attribute schema



26
27
28
# File 'lib/respect/dsl_dumper.rb', line 26

def schema
  @schema
end

Instance Method Details

- (Object) <<(str)



39
40
41
42
# File 'lib/respect/dsl_dumper.rb', line 39

def <<(str)
  @output << str.gsub(/(\n+)/, "\\1#{indentation}")
  self
end

- (Object) dump(output = nil)



28
29
30
31
32
33
34
35
36
37
# File 'lib/respect/dsl_dumper.rb', line 28

def dump(output = nil)
  @output = output
  @output ||= String.new
  self << "Respect::Schema.define do |s|"
  self.indent do
    self.dump_schema(@schema)
  end
  self << "\nend\n"
  @output
end

- (Object) dump_arguments(schema)



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/respect/dsl_dumper.rb', line 97

def dump_arguments(schema)
  # Fetch name if there is one?
  if self.context_data.has_key?(:name)
    name = self.context_data[:name]
  else
    name = nil
  end
  # Compute options to dump.
  options = schema.non_default_options.reject do |opt|
    opt == :doc
  end
  # Dump name and options
  if name || !options.empty?
    if name
      self << " "
      self << name.inspect
    end
    if !options.empty?
      if name
        self << ","
      end
      self << " "
      self.dump_options(schema)
    end
  end
  self
end

- (Object) dump_block(args = [ "s" ], &block)



62
63
64
65
66
# File 'lib/respect/dsl_dumper.rb', line 62

def dump_block(args = [ "s" ], &block)
  self << " do |#{args.join(', ')}|"
  self.indent(&block)
  self << "\nend"
end

- (Object) dump_body(schema)



137
138
139
140
141
142
# File 'lib/respect/dsl_dumper.rb', line 137

def dump_body(schema)
  symbol = "dump_body_for_#{schema.class.statement_name}"
  if respond_to? symbol
    send(symbol, schema)
  end
end

- (Object) dump_body_for_array(schema)



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/respect/dsl_dumper.rb', line 153

def dump_body_for_array(schema)
  dump_block do
    context_data.delete(:name)
    if schema.item
      dump_schema(schema.item)
    end
    if schema.items && !schema.items.empty?
      self << "\ns.items do |s|"
      indent do
        schema.items.each do |schema|
          dump_schema(schema)
        end
      end
      self << "\nend"
    end
    if schema.extra_items && !schema.extra_items.empty?
      self << "\ns.extra_items do |s|"
      indent do
        schema.extra_items.each do |schema|
          dump_schema(schema)
        end
      end
      self << "\nend"
    end
  end
end

- (Object) dump_body_for_hash(schema)



144
145
146
147
148
149
150
151
# File 'lib/respect/dsl_dumper.rb', line 144

def dump_body_for_hash(schema)
  dump_block do
    schema.properties.each do |name, schema|
      context_data[:name] = name
      dump_schema(schema)
    end
  end
end

- (Object) dump_doc(schema, prefix = false)



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/respect/dsl_dumper.rb', line 77

def dump_doc(schema, prefix = false)
  if schema.doc
    if schema.description
      self << "\n"
      self << %q{s.doc <<-EOS.strip_heredoc}
      self.indent do
        self << "\n"
        self << schema.doc
        self << "EOS"
      end
    else
      self << "\ns.doc \"#{schema.title}\""
    end
  end
end

- (Object) dump_name(schema)



93
94
95
# File 'lib/respect/dsl_dumper.rb', line 93

def dump_name(schema)
  self << schema.class.statement_name
end

- (Object) dump_options(schema)



125
126
127
128
129
130
131
132
133
134
135
# File 'lib/respect/dsl_dumper.rb', line 125

def dump_options(schema)
  options = schema.non_default_options
  option_keys = options.keys
  option_keys.each do |opt|
    self << opt.inspect
    self << " => "
    self << options[opt].inspect
    self << ", " unless opt == option_keys.last
  end
  self
end

- (Object) dump_schema(schema)



68
69
70
71
72
73
74
75
# File 'lib/respect/dsl_dumper.rb', line 68

def dump_schema(schema)
  self.dump_doc(schema)
  self << "\ns."
  self.dump_name(schema)
  self.dump_arguments(schema)
  self.dump_body(schema)
  self
end

- (Object) indent(count = 1, &block)



44
45
46
47
48
49
50
# File 'lib/respect/dsl_dumper.rb', line 44

def indent(count = 1, &block)
  @indent_level += count
  if block
    block.call
    unindent(count)
  end
end

- (Object) indentation



56
57
58
# File 'lib/respect/dsl_dumper.rb', line 56

def indentation
  " " * @indent_size * @indent_level
end

- (Object) unindent(count = 1)



52
53
54
# File 'lib/respect/dsl_dumper.rb', line 52

def unindent(count = 1)
  @indent_level -= count
end