class CC::Yaml::Parser::Psych

Constants

BINARY
BOOL
CLASS_LOADER
FALSE
FLOAT
FORMATS
INT
MAP
MERGE
NO_ANALYSIS_KEY_FOUND_ERROR
NULL
OMAP
PAIRS
REGEXP
REG_FLAGS
SECURE
SEQ
SET
STR
ScalarScanner
TIMESTAMP
TRUE
VALUE
YAML

Public Class Methods

new(value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 72
def initialize(value)
  value    = value.to_str if value.respond_to? :to_str
  value    = value.to_io  if value.respond_to? :to_io
  @value   = value
  @scanner = ScalarScanner.new
end
parse(value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 68
def self.parse(value)
  new(value).parse
end
parses?(value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 61
def self.parses?(value)
  return true if value.is_a?(::Psych::Nodes::Node)
  return true if value.is_a?(String) or value.is_a?(IO)
  return true if defined?(StringIO) and value.is_a?(StringIO)
  value.respond_to?(:to_str) or value.respond_to?(:to_io)
end

Public Instance Methods

accept(node, value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 100
def accept(node, value)
  case value
  when ::Psych::Nodes::Scalar   then accept_scalar   node, value
  when ::Psych::Nodes::Mapping  then accept_mapping  node, value
  when ::Psych::Nodes::Sequence then accept_sequence node, value
  when ::Psych::Nodes::Alias    then accept_alias    node, value
  when ::Psych::Nodes::Document then accept          node, value.root
  when ::Psych::Nodes::Stream   then accept_sequence node, value
  else node.visit_unexpected(self, value) if value
  end
  node.verify
end
accept_mapping(node, value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 125
def accept_mapping(node, value)
  case value.tag
  when MAP, OMAP, PAIRS then node.visit_mapping  self, value
  when SET              then node.visit_sequence self, SetNode.new(value)
  when SEQ              then node.visit_sequence self, value
  when nil
    if value.children.size == 2 and value.children.first.value == "secure"
      secret_value = value.children.last
      if secret_value.is_a? ::Psych::Nodes::Scalar
        secret_value.tag ||= "!secure"
        node.visit_scalar(self, :secure, secret_value, false)
      else
        node.visit_unexpected(self, value, "secret value needs to be a string")
      end
    else
      node.visit_mapping(self, value)
    end
  else
    node.visit_unexpected self, value, "unexpected tag %p for mapping" % value.tag
  end
end
accept_scalar(node, value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 147
def accept_scalar(node, value)
  case tag = scalar_tag(value)
  when BINARY    then node.visit_scalar self, :binary, value, value.tag.nil?
  when BOOL      then node.visit_scalar self, :bool,   value, value.tag.nil?
  when FLOAT     then node.visit_scalar self, :float,  value, value.tag.nil?
  when INT       then node.visit_scalar self, :int,    value, value.tag.nil?
  when NULL      then node.visit_scalar self, :null,   value, value.tag.nil?
  when STR       then node.visit_scalar self, :str,    value, value.tag.nil?
  when TIMESTAMP then node.visit_scalar self, :time,   value, value.tag.nil?
  when SECURE    then node.visit_scalar self, :secure, value, value.tag.nil?
  when NULL      then node.visit_scalar self, :null,   value, value.tag.nil?
  when REGEXP    then node.visit_scalar self, :regexp, value, value.tag.nil?
  else node.visit_unexpected self, value, "unexpected tag %p for scalar %p" % [tag, simple(value)]
  end
end
accept_sequence(node, value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 113
def accept_sequence(node, value)
  case value.tag
  when SET, SEQ
    node.visit_sequence self, value
  when nil
    value = ScalarSequence.new(value) unless value.is_a? ::Psych::Nodes::Sequence
    node.visit_sequence self, value
  else
    node.visit_sequence self, ScalarSequence.new(value)
  end
end
apply_mapping(node, value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 225
def apply_mapping(node, value)
  keys, values = value.children.group_by.with_index { |_,i| i.even? }.values_at(true, false)
  keys.zip(values) { |key, value| node.visit_pair(self, key, value) } if keys and values
end
apply_sequence(node, value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 230
def apply_sequence(node, value)
  value.children.each { |child| node.visit_child(self, child) }
end
cast(type, value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 210
def cast(type, value)
  case type
  when :str    then value.value
  when :binary then value.value.unpack("m").first
  when :bool   then value.value !~ FALSE
  when :float  then Float   @scanner.tokenize(value.value)
  when :int    then Integer @scanner.tokenize(value.value)
  when :time   then @scanner.parse_time(value.value)
  when :secure then SecureString.new(value.value, value.tag != "!decrypted")
  when :regexp then regexp(value.value)
  when :null   then nil
  else raise ArgumentError, "unknown scalar type %p" % type
  end
end
check_for_analysis_key(root) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 94
def check_for_analysis_key(root)
  unless root.engines? || root.languages? || root.errors.any?
    root.error NO_ANALYSIS_KEY_FOUND_ERROR
  end
end
generate_key(node, value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 234
def generate_key(node, value)
  if value.respond_to? :value and (value.tag.nil? || value.tag == STR)
    value = value.value.to_s
    value.start_with?(?:) ? value[1..-1] : value
  else
    node.visit_unexpected(self, value, "expected string as key")
  end
end
node_wrapper_class(value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 163
def node_wrapper_class(value)
  case value
  when ::Psych::Nodes::Scalar   then ::CC::Yaml::Nodes::Scalar
  when ::Psych::Nodes::Mapping  then ::CC::Yaml::Nodes::OpenMapping
  when ::Psych::Nodes::Sequence then ::CC::Yaml::Nodes::Sequence
  when ::Psych::Nodes::Document then ::CC::Yaml::Nodes::OpenMapping
  when ::Psych::Nodes::Stream   then ::CC::Yaml::Nodes::Sequence
  else raise ArgumentError, "Can't coerce #{value.inspect}"
  end
end
parse(root = nil) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 79
def parse(root = nil)
  root   ||= CC::Yaml::Nodes::Root.new
  parsed   = @value if @value.is_a? ::Psych::Nodes::Node
  parsed ||= ::Psych.parse(@value)
  accept(root, parsed)
  check_for_analysis_key(root)
  root
rescue ::Psych::SyntaxError => error
  root.verify
  root.warnings.clear
  root.error("syntax error: %s", error.message)
  root.parseable = false
  root
end
regexp(pattern) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 201
def regexp(pattern)
  return pattern if pattern.is_a? Regexp
  return Regexp.new(pattern) unless pattern =~ FORMATS["!regexp"]
  flag = $2.chars.inject(0) { |f,c| f | REG_FLAGS.fetch(c, 0) }
  Regexp.new($1, flag)
rescue RegexpError => error
  raise ArgumentError, "broken regular expression - #{error.message}"
end
scalar_tag(value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 192
def scalar_tag(value)
  return value.tag if value.tag
  return "!str" if value.quoted
  FORMATS.each do |tag, format|
    return tag if value.value =~ format
  end
  "!str"
end
simple(value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 174
def simple(value)
  case value
  when ::Psych::Nodes::Scalar   then value.value
  when ::Psych::Nodes::Mapping  then simple_mapping(value)
  when ::Psych::Nodes::Sequence then value.children.map { |c| simple(c) }
  when ::Psych::Nodes::Document then simple(value.root)
  when ::Psych::Nodes::Stream   then value.children.map { |c| simple(c) }
  else value
  end
end
simple_mapping(value) click to toggle source
# File lib/cc/yaml/parser/psych.rb, line 185
def simple_mapping(value)
  children     = {}
  keys, values = value.children.group_by.with_index { |_,i| i.even? }.values_at(true, false)
  keys.zip(values) { |key, value| children[simple(key)] = simple(value) } if keys and values
  children
end