class AWS::Core::XML::Grammar

A class that simplifies building XML {Parser} rules. This is also a compatability layer between the old and new formats of the api config.

Attributes

rules[R]

@return [Hash] Returns a hash of rules defined by this grammar.

Public Class Methods

customize(customizations = nil, rules = {}) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 76
def self.customize customizations = nil, rules = {}, opts = {}, &block
  grammar = self.new(deep_copy(rules), opts)
  grammar.send(:apply_customizations, customizations) if customizations
  grammar.instance_eval(&block) if block_given?
  grammar
end
new(rules = {}) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 23
def initialize rules = {}, options = {}
  @rules = rules
  @context = @rules
  @element_name = 'xml'
  @inflect_rename = options.key?(:inflect_rename) ?
    options[:inflect_rename] : true
end
parse(xml) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 83
def self.parse xml
  self.new.parse(xml)
end

Protected Class Methods

deep_copy(rules) click to toggle source

Performs a deep copy of the rules hash so that it can be customized without chaning the parent grammar.

# File lib/aws/core/xml/grammar.rb, line 91
def self.deep_copy rules
  rules.inject({}) do |copy,(key,value)|
    copy[key] = value.is_a?(Hash) ? deep_copy(value) : value
    copy
  end
end

Public Instance Methods

customize(customizations = nil, &block) click to toggle source

Returns a new grammar (leaving the current one un-modified) with the given customizations applied. Customizations can be given in a hash-form or in a block form.

@example Block-form customizations

grammar.customize do
  element "EnumElement" do
    symbol_value
    list
  end
end

@example Hash-form customizations

grammar.customize "EnumElement" => [:symbol_value, :list]

@return [Grammar] Returns a grammar with the given customizations

applied.
# File lib/aws/core/xml/grammar.rb, line 63
def customize customizations = nil, &block
  opts = { :inflect_rename => @inflect_rename }
  self.class.customize(customizations, @rules, opts, &block)
end
customize!(customizations = nil, &block) click to toggle source

Applies customizations to the current grammar, not returning a new grammar.

# File lib/aws/core/xml/grammar.rb, line 70
def customize! customizations = nil, &block
  apply_customizations(customizations) if customizations
  instance_eval(&block) if block_given?
  self
end
parse(xml) click to toggle source

Parses the XML with the rules provided by the current grammar.

This method is meant to provide backwards compatability with the old XmlGrammar class that handled rules and parsing. @param [String] xml @return [Data] Returns a hash-like parsed response.

# File lib/aws/core/xml/grammar.rb, line 36
def parse xml
  Data.new(Parser.parse(xml, rules))
end

Protected Instance Methods

==(other) click to toggle source
Alias for: eql?
apply_customizations(customizations) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 98
def apply_customizations customizations
  customizations.each do |item|
    (type, identifier, args) = parse_customization_item(item)
    case type
    when :method
      validate_config_method(identifier)
      validate_args(identifier, args)
      send(identifier, *args)
    when :element
      element(identifier) do
        apply_customizations(args)
      end
    end
  end
end
blob() click to toggle source
Alias for: blob_value
blob_value() click to toggle source
# File lib/aws/core/xml/grammar.rb, line 247
def blob_value
  @context[:type] = :blob
end
Also aliased as: blob
boolean() click to toggle source
Alias for: boolean_value
boolean_value() click to toggle source
# File lib/aws/core/xml/grammar.rb, line 242
def boolean_value
  @context[:type] = :boolean
end
Also aliased as: boolean
collect_values() click to toggle source
# File lib/aws/core/xml/grammar.rb, line 194
def collect_values
  @context[:list] = true
end
construct_value(&block) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 238
def construct_value &block
  raise 'remove the need for this'
end
context_for_child(child_element_name) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 290
def context_for_child child_element_name
  @context[:children] ||= {}
  @context[:children][child_element_name] ||= {}
  @context[:children][child_element_name]
end
datetime() click to toggle source
Alias for: datetime_value
datetime_value() click to toggle source
# File lib/aws/core/xml/grammar.rb, line 252
def datetime_value
  @context[:type] = :datetime
end
Also aliased as: datetime
default_value(name, value) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 202
def default_value name, value
  @context[:defaults] ||= {}
  @context[:defaults][name] = value
end
element(element_name) { |parent_element_name| ... } click to toggle source

customization methods

# File lib/aws/core/xml/grammar.rb, line 158
def element element_name, &block

  parent_context = @context
  parent_element_name = @element_name
  
  @context = context_for_child(element_name)

  @element_name = element_name

  begin
    if block_given?
      block.arity == 1 ? yield(parent_element_name) : yield   
    end
  ensure
    @context = parent_context
    @element_name = parent_element_name
  end

end
eql?(other) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 284
def eql? other
  other.is_a?(Grammar) and self.rules == other.rules
end
Also aliased as: ==
float() click to toggle source
Alias for: float_value
float_value() click to toggle source
# File lib/aws/core/xml/grammar.rb, line 274
def float_value
  @context[:type] = :float
end
Also aliased as: float
force() click to toggle source
# File lib/aws/core/xml/grammar.rb, line 190
def force
  @context[:force] = true
end
ignore() click to toggle source
# File lib/aws/core/xml/grammar.rb, line 178
def ignore
  @context[:ignore] = true
end
index(index_name, options = {}) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 198
def index index_name, options = {}
  @context[:index] = options.merge(:name => index_name)
end
inflect(value) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 150
def inflect value
  Inflection.ruby_name(value.to_s).to_sym
end
integer() click to toggle source
Alias for: integer_value
integer_value() click to toggle source
# File lib/aws/core/xml/grammar.rb, line 268
def integer_value
  @context[:type] = :integer
end
Also aliased as: integer, long
list(child_element_name = nil) { || ... } click to toggle source
# File lib/aws/core/xml/grammar.rb, line 207
def list child_element_name = nil, &block
  if child_element_name
    ignore
    element(child_element_name) do |parent_element_name|
      rename(parent_element_name)
      collect_values
      yield if block_given?
    end
  else
    collect_values
  end
end
long() click to toggle source
Alias for: integer_value
map(map_element_name, key_element_name, value_element_name) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 224
def map map_element_name, key_element_name, value_element_name
  ignore
  element(map_element_name) do |parent_element_name|
    rename(parent_element_name)  
    map_entry(key_element_name, value_element_name)
  end
end
map_entry(key_element_name, value_element_name) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 220
def map_entry key_element_name, value_element_name
  @context[:map] = [key_element_name, value_element_name]
end
parse_customization_item(item) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 114
def parse_customization_item item
  case item
  when Symbol
    [:method, item, []]
  when Hash
    (method, arg) = item.to_a.first
    if method.kind_of?(Symbol)
      [:method, method, [arg].flatten]
    else
      [:element, method, arg]
    end
  end
end
rename(new_name) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 182
def rename new_name
  if @inflect_rename
    @context[:rename] = inflect(new_name)
  else
    @context[:rename] = new_name
  end
end
string() click to toggle source
Alias for: string_value
string_value() click to toggle source
# File lib/aws/core/xml/grammar.rb, line 263
def string_value
  @context[:type] = :string
end
Also aliased as: string
symbol() click to toggle source
Alias for: symbol_value
symbol_value() click to toggle source
# File lib/aws/core/xml/grammar.rb, line 279
def symbol_value
  @context[:type] = :symbol
end
Also aliased as: symbol
time() click to toggle source
Alias for: time_value
time_value() click to toggle source
# File lib/aws/core/xml/grammar.rb, line 257
def time_value
  @context[:type] = :time
end
Also aliased as: timestamp, time
timestamp() click to toggle source
Alias for: time_value
validate_args(identifier, args) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 139
def validate_args(identifier, args)
  arity = method(identifier).arity
  if args.length > 0
    raise "#{identifier} does not accept an argument" if
      arity == 0
  else
    raise "#{identifier} requires an argument" unless
      arity == 0 || arity == -1
  end
end
validate_config_method(method) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 128
def validate_config_method(method)
  allow_methods = %w(
    rename attribute_name boolean integer long float list force
    ignore collect_values symbol_value timestamp map_entry map
    blob string
  )
  unless allow_methods.include?(method.to_s)
    raise "#{method} cannot be used in configuration"
  end
end
wrapper(method_name, options = {}) click to toggle source
# File lib/aws/core/xml/grammar.rb, line 232
def wrapper method_name, options = {}, &block
  options[:for].each do |child|
    context_for_child(child)[:wrap] = method_name
  end
end