summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2010-02-17 22:44:26 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2010-02-17 22:44:26 -0800
commitebf212880db752979336cfc613bac7c3d0d83d32 (patch)
treebd9853664f5dab8da1d34f817516a54e0d05a219 /lib
parent7e3a927e6b7e1a63bc16b9c74eb931dc3eb6a983 (diff)
downloadpsych-ebf212880db752979336cfc613bac7c3d0d83d32.zip
adding basic json support
Diffstat (limited to 'lib')
-rw-r--r--lib/psych.rb8
-rw-r--r--lib/psych/visitors.rb1
-rw-r--r--lib/psych/visitors/json_tree.rb37
-rw-r--r--lib/psych/visitors/yaml_tree.rb33
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