diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/psych.rb | 7 | ||||
-rw-r--r-- | lib/psych/nodes/document.rb | 4 | ||||
-rw-r--r-- | lib/psych/nodes/node.rb | 1 | ||||
-rw-r--r-- | lib/psych/ruby.rb | 13 | ||||
-rw-r--r-- | lib/psych/tree_builder.rb | 13 | ||||
-rw-r--r-- | lib/psych/visitors.rb | 1 | ||||
-rw-r--r-- | lib/psych/visitors/emitter.rb | 12 | ||||
-rw-r--r-- | lib/psych/visitors/yast_builder.rb | 45 |
8 files changed, 92 insertions, 4 deletions
diff --git a/lib/psych.rb b/lib/psych.rb index bbb8662..3ebc1fa 100644 --- a/lib/psych.rb +++ b/lib/psych.rb @@ -13,6 +13,7 @@ require 'psych/visitors' require 'psych/handler' require 'psych/tree_builder' require 'psych/parser' +require 'psych/ruby' require 'psych/psych' module Psych @@ -22,8 +23,12 @@ module Psych ### # Load +yaml+ in to a Ruby data structure def self.load yaml + parse(yaml).to_ruby + end + + def self.parse yaml parser = Psych::Parser.new(TreeBuilder.new) parser.parse yaml - parser.handler.root.children.first.to_ruby + parser.handler.root.children.first.children.first end end diff --git a/lib/psych/nodes/document.rb b/lib/psych/nodes/document.rb index be786c6..4f46644 100644 --- a/lib/psych/nodes/document.rb +++ b/lib/psych/nodes/document.rb @@ -10,11 +10,15 @@ module Psych # Was this document implicitly created? attr_accessor :implicit + # Is the end of the document implicit? + attr_accessor :implicit_end + def initialize version = [], tag_directives = [], implicit = false super() @version = version @tag_directives = tag_directives @implicit = implicit + @implicit_end = true end ### diff --git a/lib/psych/nodes/node.rb b/lib/psych/nodes/node.rb index a63fc60..6aaba15 100644 --- a/lib/psych/nodes/node.rb +++ b/lib/psych/nodes/node.rb @@ -17,6 +17,7 @@ module Psych def to_ruby Visitors::ToRuby.new.accept self end + alias :transform :to_ruby def to_yaml io = StringIO.new diff --git a/lib/psych/ruby.rb b/lib/psych/ruby.rb new file mode 100644 index 0000000..6802391 --- /dev/null +++ b/lib/psych/ruby.rb @@ -0,0 +1,13 @@ +[Object, String, Class, Hash].each do |klass| + klass.send(:remove_method, :to_yaml) +end + +class Object + include Psych::Visitable + + def to_yaml options = {} + visitor = Psych::Visitors::YASTBuilder.new options + visitor.accept self + visitor.tree.to_yaml + end +end diff --git a/lib/psych/tree_builder.rb b/lib/psych/tree_builder.rb index efbeaf9..089ee96 100644 --- a/lib/psych/tree_builder.rb +++ b/lib/psych/tree_builder.rb @@ -17,7 +17,6 @@ module Psych end %w{ - Document Sequence Mapping }.each do |node| @@ -28,12 +27,22 @@ module Psych @stack.push n end - def end_#{node.downcase}(*args) + def end_#{node.downcase} @stack.pop end } end + def start_document(*args) + n = Nodes::Document.new(*args) + @stack.last.children << n + @stack.push n + end + + def end_document implicit_end + @stack.pop.implicit_end = implicit_end + end + def start_stream encoding @stack.push Nodes::Stream.new(encoding) end diff --git a/lib/psych/visitors.rb b/lib/psych/visitors.rb index df58e2e..0708e94 100644 --- a/lib/psych/visitors.rb +++ b/lib/psych/visitors.rb @@ -1,3 +1,4 @@ require 'psych/visitors/visitor' require 'psych/visitors/to_ruby' require 'psych/visitors/emitter' +require 'psych/visitors/yast_builder' diff --git a/lib/psych/visitors/emitter.rb b/lib/psych/visitors/emitter.rb index a0ff9d9..3e33095 100644 --- a/lib/psych/visitors/emitter.rb +++ b/lib/psych/visitors/emitter.rb @@ -14,7 +14,7 @@ module Psych visitor_for(Nodes::Document) do |o| @handler.start_document o.version, o.tag_directives, o.implicit o.children.each { |c| c.accept self } - @handler.end_document o.implicit + @handler.end_document o.implicit_end end visitor_for(Nodes::Scalar) do |o| @@ -26,6 +26,16 @@ module Psych o.children.each { |c| c.accept self } @handler.end_sequence end + + visitor_for(Nodes::Mapping) do |o| + @handler.start_mapping o.anchor, o.tag, o.implicit, o.style + o.children.each { |c| c.accept self } + @handler.end_mapping + end + + visitor_for(Nodes::Alias) do |o| + @handler.alias o.anchor + end end end end diff --git a/lib/psych/visitors/yast_builder.rb b/lib/psych/visitors/yast_builder.rb new file mode 100644 index 0000000..00f533f --- /dev/null +++ b/lib/psych/visitors/yast_builder.rb @@ -0,0 +1,45 @@ +module Psych + module Visitors + class YASTBuilder < Psych::Visitors::Visitor + attr_reader :tree + + def initialize options = {} + super() + @tree = Nodes::Stream.new + @tree.children << Nodes::Document.new + @stack = @tree.children.dup + end + + def accept target + target.class.ancestors.each do |klass| + method_name = :"visit_#{target.class.name.split('::').join('_')}" + if respond_to?(method_name) + return send(method_name, target) + end + end + raise TypeError, "Can't dump #{target.class}" + end + + visitor_for(::String) do |o| + @stack.last.children << Nodes::Scalar.new(o) + end + + visitor_for(::Class) do |o| + raise TypeError, "can't dump anonymous class #{o.class}" + end + + visitor_for(::Hash) do |o| + map = Nodes::Mapping.new + @stack.last.children << map + @stack.push map + + o.each do |k,v| + k.accept self + v.accept self + end + + @stack.pop + end + end + end +end |