1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/psych/lib/psych/json/stream.rb: adding a JSON streaming API

* ext/psych/lib/psych/stream.rb: ditto
* ext/psych/lib/psych.rb: using autoload
* ext/psych/lib/psych/json.rb: ditto
* ext/psych/lib/psych/json/tree_builder.rb: refactor
* ext/psych/lib/psych/visitors/json_tree.rb: refactor

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27961 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
tenderlove 2010-05-22 22:12:39 +00:00
parent eb5f96d70c
commit 044d6010fd
8 changed files with 140 additions and 19 deletions

View file

@ -1,3 +1,18 @@
Sun May 23 07:08:34 2010 Aaron Patterson <aaron@tenderlovemaking.com>
* ext/psych/lib/psych/json/stream.rb: adding a JSON streaming API
* ext/psych/lib/psych/stream.rb: ditto
* ext/psych/lib/psych.rb: using autoload
* ext/psych/lib/psych/json.rb: ditto
* ext/psych/lib/psych/json/tree_builder.rb: refactor
* ext/psych/lib/psych/visitors/json_tree.rb: refactor
Sat May 22 03:53:05 2010 Satoshi Shiba <shiba@rvm.jp>
* cont.c (fiber_setcontext): Use swapcontext() instead longjmp().

View file

@ -3,7 +3,6 @@ require 'psych/nodes'
require 'psych/visitors'
require 'psych/handler'
require 'psych/tree_builder'
require 'psych/json/tree_builder'
require 'psych/parser'
require 'psych/omap'
require 'psych/set'
@ -98,6 +97,7 @@ module Psych
end
autoload :Stream, 'psych/stream'
autoload :JSON, 'psych/json'
###
# Load +yaml+ in to a Ruby data structure. If multiple documents are

View file

@ -0,0 +1,6 @@
module Psych
module JSON
autoload :TreeBuilder, 'psych/json/tree_builder'
autoload :Stream, 'psych/json/stream'
end
end

View file

@ -0,0 +1,32 @@
module Psych
module JSON
class Stream < Psych::Stream
class Emitter < Psych::Stream::Emitter # :nodoc:
def start_document version, tag_directives, implicit
super(version, tag_directives, !streaming?)
end
def start_mapping anchor, tag, implicit, style
super(anchor, tag, implicit, Nodes::Mapping::FLOW)
end
def start_sequence anchor, tag, implicit, style
super(anchor, tag, implicit, Nodes::Sequence::FLOW)
end
def scalar value, anchor, tag, plain, quoted, style
if "tag:yaml.org,2002:null" == tag
super('null', nil, nil, true, false, Nodes::Scalar::PLAIN)
else
super
end
end
end
def visit_String o
@emitter.scalar o.to_s, nil, nil, false, true, Nodes::Scalar::ANY
end
alias :visit_Symbol :visit_String
end
end
end

View file

@ -5,11 +5,11 @@ module Psych
# to an instance of Psych::JSON::TreeBuilder and a JSON AST is constructed.
class TreeBuilder < Psych::TreeBuilder
def start_document version, tag_directives, implicit
super(version, tag_directives, true)
super(version, tag_directives, !streaming?)
end
def end_document implicit_end = !streaming?
super(true)
super(implicit_end)
end
def start_mapping anchor, tag, implicit, style
@ -19,6 +19,14 @@ module Psych
def start_sequence anchor, tag, implicit, style
super(anchor, tag, implicit, Nodes::Sequence::FLOW)
end
def scalar value, anchor, tag, plain, quoted, style
if "tag:yaml.org,2002:null" == tag
super('null', nil, nil, true, false, Nodes::Scalar::PLAIN)
else
super
end
end
end
end
end

View file

@ -35,7 +35,7 @@ module Psych
# Create a new streaming emitter. Emitter will print to +io+. See
# Psych::Stream for an example.
def initialize io
super({}, Emitter.new(io))
super({}, self.class.const_get(:Emitter).new(io))
end
###

View file

@ -5,25 +5,10 @@ module Psych
super
end
def visit_NilClass o
@emitter.scalar 'null', nil, nil, true, false, Nodes::Scalar::PLAIN
end
def visit_Integer o
@emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::PLAIN
end
def visit_Float o
return super if o.nan? || o.infinite?
visit_Integer o
end
def visit_String o
@emitter.scalar o.to_s, nil, nil, false, true, Nodes::Scalar::ANY
end
alias :visit_Symbol :visit_String
private
end
end
end

View file

@ -0,0 +1,75 @@
require_relative '../helper'
module Psych
module JSON
class TestStream < TestCase
def setup
@io = StringIO.new
@stream = Psych::JSON::Stream.new(@io)
@stream.start
end
def test_explicit_documents
@io = StringIO.new
@stream = Psych::JSON::Stream.new(@io)
@stream.start
@stream.push({ 'foo' => 'bar' })
assert !@stream.finished?, 'stream not finished'
@stream.finish
assert @stream.finished?, 'stream finished'
assert_match(/^---/, @io.string)
assert_match(/\.\.\.$/, @io.string)
end
def test_null
@stream.push(nil)
assert_match(/^--- null/, @io.string)
end
def test_string
@stream.push "foo"
assert_match(/(['"])foo\1/, @io.string)
end
def test_symbol
@stream.push :foo
assert_match(/(['"])foo\1/, @io.string)
end
def test_int
@stream.push 10
assert_match(/^--- 10/, @io.string)
end
def test_float
@stream.push 1.2
assert_match(/^--- 1.2/, @io.string)
end
def test_hash
hash = { 'one' => 'two' }
@stream.push hash
json = @io.string
assert_match(/}$/, json)
assert_match(/^--- \{/, json)
assert_match(/['"]one['"]/, json)
assert_match(/['"]two['"]/, json)
end
def test_list_to_json
list = %w{ one two }
@stream.push list
json = @io.string
assert_match(/]$/, json)
assert_match(/^--- \[/, json)
assert_match(/['"]one['"]/, json)
assert_match(/['"]two['"]/, json)
end
end
end
end