diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2010-02-17 22:44:26 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2010-02-17 22:44:26 -0800 |
commit | ebf212880db752979336cfc613bac7c3d0d83d32 (patch) | |
tree | bd9853664f5dab8da1d34f817516a54e0d05a219 /lib | |
parent | 7e3a927e6b7e1a63bc16b9c74eb931dc3eb6a983 (diff) | |
download | psych-ebf212880db752979336cfc613bac7c3d0d83d32.zip |
adding basic json support
Diffstat (limited to 'lib')
-rw-r--r-- | lib/psych.rb | 8 | ||||
-rw-r--r-- | lib/psych/visitors.rb | 1 | ||||
-rw-r--r-- | lib/psych/visitors/json_tree.rb | 37 | ||||
-rw-r--r-- | lib/psych/visitors/yaml_tree.rb | 33 |
4 files changed, 71 insertions, 8 deletions
diff --git a/lib/psych.rb b/lib/psych.rb index 0c4a7ee..5f66849 100644 --- a/lib/psych.rb +++ b/lib/psych.rb @@ -144,6 +144,14 @@ module Psych end ### + # Dump Ruby object +o+ to a JSON string. + def self.to_json o + visitor = Psych::Visitors::JSONTree.new(:json => true) + visitor.accept o + visitor.tree.to_yaml + end + + ### # Load multiple documents given in +yaml+, yielding each document to # the block provided. def self.load_documents yaml, &block diff --git a/lib/psych/visitors.rb b/lib/psych/visitors.rb index d00dcfd..10ac4ce 100644 --- a/lib/psych/visitors.rb +++ b/lib/psych/visitors.rb @@ -2,3 +2,4 @@ require 'psych/visitors/visitor' require 'psych/visitors/to_ruby' require 'psych/visitors/emitter' require 'psych/visitors/yaml_tree' +require 'psych/visitors/json_tree' diff --git a/lib/psych/visitors/json_tree.rb b/lib/psych/visitors/json_tree.rb new file mode 100644 index 0000000..0440dc7 --- /dev/null +++ b/lib/psych/visitors/json_tree.rb @@ -0,0 +1,37 @@ +module Psych + module Visitors + class JSONTree < YAMLTree + def visit_Symbol o + append create_scalar o.to_s + end + + def visit_NilClass o + scalar = Nodes::Scalar.new( + 'null', nil, nil, true, false, Nodes::Scalar::PLAIN) + append scalar + end + + private + def create_document + doc = super + doc.implicit = true + doc.implicit_end = true + doc + end + + def create_mapping + map = super + map.style = Nodes::Mapping::FLOW + map + end + + def create_scalar value, anchor = nil, tag = nil, plain = false, quoted = true, style = Nodes::Scalar::ANY + super(value, anchor, tag, false, true, style) + end + + def create_sequence anchor = nil, tag = nil, implicit = true, style = Nodes::Sequence::FLOW + super + end + end + end +end diff --git a/lib/psych/visitors/yaml_tree.rb b/lib/psych/visitors/yaml_tree.rb index 2efbb61..15cc494 100644 --- a/lib/psych/visitors/yaml_tree.rb +++ b/lib/psych/visitors/yaml_tree.rb @@ -5,8 +5,9 @@ module Psych def initialize options = {} super() + @json = options[:json] @tree = Nodes::Stream.new - @tree.children << Nodes::Document.new + @tree.children << create_document @stack = @tree.children.dup @st = {} @ss = ScalarScanner.new @@ -165,7 +166,7 @@ module Psych o.to_yaml_properties : o.instance_variables - scalar = Nodes::Scalar.new str, nil, tag, plain, quote + scalar = create_scalar str, nil, tag, plain, quote if ivars.empty? append scalar @@ -194,7 +195,7 @@ module Psych end def visit_Hash o - @stack.push append register(o, Nodes::Mapping.new) + @stack.push append register(o, create_mapping) o.each do |k,v| accept k @@ -216,7 +217,7 @@ module Psych end def visit_Array o - @stack.push append register(o, Nodes::Sequence.new) + @stack.push append register(o, create_sequence) o.each { |c| accept c } @stack.pop end @@ -226,7 +227,7 @@ module Psych end def visit_Symbol o - append Nodes::Scalar.new ":#{o}" + append create_scalar ":#{o}" end private @@ -255,12 +256,12 @@ module Psych def emit_coder c case c.type when :scalar - append Nodes::Scalar.new(c.scalar, nil, c.tag, c.tag.nil?) + append create_scalar(c.scalar, nil, c.tag, c.tag.nil?) when :map map = append Nodes::Mapping.new(nil, c.tag, c.implicit, c.style) @stack.push map c.map.each do |k,v| - map.children << Nodes::Scalar.new(k) + map.children << create_scalar(k) accept v end @stack.pop @@ -273,10 +274,26 @@ module Psych target.instance_variables ivars.each do |iv| - map.children << Nodes::Scalar.new("#{iv.to_s.sub(/^@/, '')}") + map.children << create_scalar("#{iv.to_s.sub(/^@/, '')}") accept target.instance_variable_get(iv) end end + + def create_document + Nodes::Document.new + end + + def create_mapping + Nodes::Mapping.new + end + + def create_scalar value, anchor = nil, tag = nil, plain = true, quoted = false, style = Nodes::Scalar::ANY + Nodes::Scalar.new(value, anchor, tag, plain, quoted, style) + end + + def create_sequence anchor = nil, tag = nil, implicit = true, style = Nodes::Sequence::BLOCK + Nodes::Sequence.new(anchor, tag, implicit, style) + end end end end |