Class: Travis::Yaml::Parser::Psych
- Inherits:
-
Object
- Object
- Travis::Yaml::Parser::Psych
- Defined in:
- lib/travis/yaml/parser/psych.rb
Defined Under Namespace
Classes: ScalarScanner, ScalarSequence, SetNode
Constant Summary collapse
- MAP =
/\A(?:tag:yaml\.org,2002:|!!?)map\z/
- OMAP =
/\A(?:tag:yaml\.org,2002:|!!?)omap\z/
- PAIRS =
/\A(?:tag:yaml\.org,2002:|!!?)pairs\z/
- SET =
/\A(?:tag:yaml\.org,2002:|!!?)set\z/
- SEQ =
/\A(?:tag:yaml\.org,2002:|!!?)seq\z/
- BINARY =
/\A(?:tag:yaml\.org,2002:|!!?)binary\z/
- BOOL =
/\A(?:tag:yaml\.org,2002:|!!?)bool\z/
- FLOAT =
/\A(?:tag:yaml\.org,2002:|!!?)float\z/
- INT =
/\A(?:tag:yaml\.org,2002:|!!?)int\z/
- MERGE =
/\A(?:tag:yaml\.org,2002:|!!?)merge\z/
- NULL =
/\A(?:tag:yaml\.org,2002:|!!?)null\z/
- STR =
/\A(?:tag:yaml\.org,2002:|!!?)str\z/
- TIMESTAMP =
/\A(?:tag:yaml\.org,2002:|!!?)timestamp\z/
- VALUE =
/\A(?:tag:yaml\.org,2002:|!!?)value\z/
- YAML =
/\A(?:tag:yaml\.org,2002:|!!?)yaml\z/
- SECURE =
/\A!(?:encrypted|secure|decrypted)\z/
- TRUE =
/\A(?:y|Y|yes|Yes|YES|true|True|TRUE|on|On|ON)\z/
- FALSE =
/\A(?:n|N|no|No|NO|false|False|FALSE|off|Off|OFF)\z/
- REGEXP =
/\A!(?:ruby\/)?regexp\z/
- REG_FLAGS =
{ 'i' => Regexp::IGNORECASE, 'm' => Regexp::MULTILINE, 'x' => Regexp::EXTENDED }
- FORMATS =
{ '!bool' => Regexp.union(TRUE, FALSE), '!float' => ::Psych::ScalarScanner::FLOAT, '!null' => /\A(:?~|null|Null|NULL|)\z/, '!timestamp' => ::Psych::ScalarScanner::TIME, '!int' => ::Psych::ScalarScanner::INTEGER, '!regexp' => /\A\/(.*)\/([imx]*)\z/ }
- CLASS_LOADER =
::Psych::ClassLoader.new
Class Method Summary collapse
Instance Method Summary collapse
- #accept(node, value) ⇒ Object
- #accept_mapping(node, value) ⇒ Object
- #accept_scalar(node, value) ⇒ Object
- #accept_sequence(node, value) ⇒ Object
- #apply_mapping(node, value) ⇒ Object
- #apply_sequence(node, value) ⇒ Object
- #cast(type, value) ⇒ Object
- #generate_key(node, value) ⇒ Object
-
#initialize(value) ⇒ Psych
constructor
A new instance of Psych.
- #parse(root = nil) ⇒ Object
- #regexp(pattern) ⇒ Object
- #scalar_tag(value) ⇒ Object
- #simple(value) ⇒ Object
- #simple_mapping(value) ⇒ Object
Constructor Details
#initialize(value) ⇒ Psych
Returns a new instance of Psych.
70 71 72 73 74 75 |
# File 'lib/travis/yaml/parser/psych.rb', line 70 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 |
Class Method Details
.parse(value) ⇒ Object
66 67 68 |
# File 'lib/travis/yaml/parser/psych.rb', line 66 def self.parse(value) new(value).parse end |
.parses?(value) ⇒ Boolean
59 60 61 62 63 64 |
# File 'lib/travis/yaml/parser/psych.rb', line 59 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 |
Instance Method Details
#accept(node, value) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/travis/yaml/parser/psych.rb', line 90 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) ⇒ Object
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/travis/yaml/parser/psych.rb', line 115 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) ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/travis/yaml/parser/psych.rb', line 137 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) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/travis/yaml/parser/psych.rb', line 103 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) ⇒ Object
204 205 206 207 |
# File 'lib/travis/yaml/parser/psych.rb', line 204 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) ⇒ Object
209 210 211 |
# File 'lib/travis/yaml/parser/psych.rb', line 209 def apply_sequence(node, value) value.children.each { |child| node.visit_child(self, child) } end |
#cast(type, value) ⇒ Object
189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/travis/yaml/parser/psych.rb', line 189 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 |
#generate_key(node, value) ⇒ Object
213 214 215 216 217 218 219 220 |
# File 'lib/travis/yaml/parser/psych.rb', line 213 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 |
#parse(root = nil) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/travis/yaml/parser/psych.rb', line 77 def parse(root = nil) root ||= Travis::Yaml::Nodes::Root.new parsed = @value if @value.is_a? ::Psych::Nodes::Node parsed ||= ::Psych.parse(@value) accept(root, parsed) root rescue ::Psych::SyntaxError => error root.verify root.warnings.clear root.error("syntax error: %s", error.) root end |
#regexp(pattern) ⇒ Object
180 181 182 183 184 185 186 187 |
# File 'lib/travis/yaml/parser/psych.rb', line 180 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) ⇒ Object
171 172 173 174 175 176 177 178 |
# File 'lib/travis/yaml/parser/psych.rb', line 171 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) ⇒ Object
153 154 155 156 157 158 159 160 161 162 |
# File 'lib/travis/yaml/parser/psych.rb', line 153 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) ⇒ Object
164 165 166 167 168 169 |
# File 'lib/travis/yaml/parser/psych.rb', line 164 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 |