Module: Gem::YAMLSerializer

Defined in:
lib/rubygems/yaml_serializer.rb

Overview

A stub yaml serializer that can handle only hashes and strings (as of now).

Constant Summary collapse

ARRAY_REGEX =
/
  ^
  (?:[ ]*-[ ]) # '- ' before array items
  (['"]?) # optional opening quote
  (.*) # value
  \1 # matching closing quote
  $
/xo
HASH_REGEX =
/
  ^
  ([ ]*) # indentations
  ([^#]+) # key excludes comment char '#'
  (?::(?=(?:\s|$))) # :  (without the lookahead the #key includes this when : is present in value)
  [ ]?
  (['"]?) # optional opening quote
  (.*) # value
  \3 # matching closing quote
  $
/xo

Class Method Summary collapse

Class Method Details

.dump(hash) ⇒ Object



8
9
10
11
# File 'lib/rubygems/yaml_serializer.rb', line 8

def dump(hash)
  yaml = String.new("---")
  yaml << dump_hash(hash)
end

.dump_hash(hash) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/rubygems/yaml_serializer.rb', line 13

def dump_hash(hash)
  yaml = String.new("\n")
  hash.each do |k, v|
    yaml << k << ":"
    if v.is_a?(Hash)
      yaml << dump_hash(v).gsub(/^(?!$)/, "  ") # indent all non-empty lines
    elsif v.is_a?(Array) # Expected to be array of strings
      if v.empty?
        yaml << " []\n"
      else
        yaml << "\n- " << v.map {|s| s.to_s.gsub(/\s+/, " ").inspect }.join("\n- ") << "\n"
      end
    else
      yaml << " " << v.to_s.gsub(/\s+/, " ").inspect << "\n"
    end
  end
  yaml
end

.load(str) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/rubygems/yaml_serializer.rb', line 53

def load(str)
  res = {}
  stack = [res]
  last_hash = nil
  last_empty_key = nil
  str.split(/\r?\n/) do |line|
    if match = HASH_REGEX.match(line)
      indent, key, quote, val = match.captures
      val = strip_comment(val)

      depth = indent.size / 2
      if quote.empty? && val.empty?
        new_hash = {}
        stack[depth][key] = new_hash
        stack[depth + 1] = new_hash
        last_empty_key = key
        last_hash = stack[depth]
      else
        val = [] if val == "[]" # empty array
        stack[depth][key] = val
      end
    elsif match = ARRAY_REGEX.match(line)
      _, val = match.captures
      val = strip_comment(val)

      last_hash[last_empty_key] = [] unless last_hash[last_empty_key].is_a?(Array)

      last_hash[last_empty_key].push(val)
    end
  end
  res
end

.strip_comment(val) ⇒ Object



86
87
88
89
90
91
92
# File 'lib/rubygems/yaml_serializer.rb', line 86

def strip_comment(val)
  if val.include?("#") && !val.start_with?("#")
    val.split("#", 2).first.strip
  else
    val
  end
end