mirror of
https://github.com/ruby/ruby.git
synced 2025-09-18 10:03:59 +02:00
parent
ef084cc8f4
commit
4eb51dfc9e
8 changed files with 90 additions and 47 deletions
|
@ -867,7 +867,7 @@ json_object_i(VALUE key, VALUE val, VALUE _arg)
|
||||||
if (klass == rb_cString) {
|
if (klass == rb_cString) {
|
||||||
key_to_s = key;
|
key_to_s = key;
|
||||||
} else if (klass == rb_cSymbol) {
|
} else if (klass == rb_cSymbol) {
|
||||||
key_to_s = rb_id2str(SYM2ID(key));
|
key_to_s = rb_sym2str(key);
|
||||||
} else {
|
} else {
|
||||||
key_to_s = rb_funcall(key, i_to_s, 0);
|
key_to_s = rb_funcall(key, i_to_s, 0);
|
||||||
}
|
}
|
||||||
|
@ -892,7 +892,6 @@ static void generate_json_object(FBuffer *buffer, VALUE Vstate, JSON_Generator_S
|
||||||
struct hash_foreach_arg arg;
|
struct hash_foreach_arg arg;
|
||||||
|
|
||||||
if (max_nesting != 0 && depth > max_nesting) {
|
if (max_nesting != 0 && depth > max_nesting) {
|
||||||
fbuffer_free(buffer);
|
|
||||||
rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
|
rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
|
||||||
}
|
}
|
||||||
fbuffer_append_char(buffer, '{');
|
fbuffer_append_char(buffer, '{');
|
||||||
|
@ -927,7 +926,6 @@ static void generate_json_array(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
|
||||||
long depth = ++state->depth;
|
long depth = ++state->depth;
|
||||||
int i, j;
|
int i, j;
|
||||||
if (max_nesting != 0 && depth > max_nesting) {
|
if (max_nesting != 0 && depth > max_nesting) {
|
||||||
fbuffer_free(buffer);
|
|
||||||
rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
|
rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth);
|
||||||
}
|
}
|
||||||
fbuffer_append_char(buffer, '[');
|
fbuffer_append_char(buffer, '[');
|
||||||
|
@ -1020,10 +1018,8 @@ static void generate_json_float(FBuffer *buffer, VALUE Vstate, JSON_Generator_St
|
||||||
VALUE tmp = rb_funcall(obj, i_to_s, 0);
|
VALUE tmp = rb_funcall(obj, i_to_s, 0);
|
||||||
if (!allow_nan) {
|
if (!allow_nan) {
|
||||||
if (isinf(value)) {
|
if (isinf(value)) {
|
||||||
fbuffer_free(buffer);
|
|
||||||
rb_raise(eGeneratorError, "%"PRIsVALUE" not allowed in JSON", RB_OBJ_STRING(tmp));
|
rb_raise(eGeneratorError, "%"PRIsVALUE" not allowed in JSON", RB_OBJ_STRING(tmp));
|
||||||
} else if (isnan(value)) {
|
} else if (isnan(value)) {
|
||||||
fbuffer_free(buffer);
|
|
||||||
rb_raise(eGeneratorError, "%"PRIsVALUE" not allowed in JSON", RB_OBJ_STRING(tmp));
|
rb_raise(eGeneratorError, "%"PRIsVALUE" not allowed in JSON", RB_OBJ_STRING(tmp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1096,11 +1092,45 @@ static FBuffer *cState_prepare_buffer(VALUE self)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct generate_json_data {
|
||||||
|
FBuffer *buffer;
|
||||||
|
VALUE vstate;
|
||||||
|
JSON_Generator_State *state;
|
||||||
|
VALUE obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
static VALUE generate_json_try(VALUE d)
|
||||||
|
{
|
||||||
|
struct generate_json_data *data = (struct generate_json_data *)d;
|
||||||
|
|
||||||
|
generate_json(data->buffer, data->vstate, data->state, data->obj);
|
||||||
|
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE generate_json_rescue(VALUE d, VALUE exc)
|
||||||
|
{
|
||||||
|
struct generate_json_data *data = (struct generate_json_data *)d;
|
||||||
|
fbuffer_free(data->buffer);
|
||||||
|
|
||||||
|
rb_exc_raise(exc);
|
||||||
|
|
||||||
|
return Qundef;
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE cState_partial_generate(VALUE self, VALUE obj)
|
static VALUE cState_partial_generate(VALUE self, VALUE obj)
|
||||||
{
|
{
|
||||||
FBuffer *buffer = cState_prepare_buffer(self);
|
FBuffer *buffer = cState_prepare_buffer(self);
|
||||||
GET_STATE(self);
|
GET_STATE(self);
|
||||||
generate_json(buffer, self, state, obj);
|
|
||||||
|
struct generate_json_data data = {
|
||||||
|
.buffer = buffer,
|
||||||
|
.vstate = self,
|
||||||
|
.state = state,
|
||||||
|
.obj = obj
|
||||||
|
};
|
||||||
|
rb_rescue(generate_json_try, (VALUE)&data, generate_json_rescue, (VALUE)&data);
|
||||||
|
|
||||||
return fbuffer_to_s(buffer);
|
return fbuffer_to_s(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
||||||
require 'json'
|
require 'json'
|
||||||
end
|
end
|
||||||
|
begin
|
||||||
require 'ostruct'
|
require 'ostruct'
|
||||||
|
rescue LoadError
|
||||||
|
end
|
||||||
|
|
||||||
class OpenStruct
|
class OpenStruct
|
||||||
|
|
||||||
|
@ -48,4 +51,4 @@ class OpenStruct
|
||||||
def to_json(*args)
|
def to_json(*args)
|
||||||
as_json.to_json(*args)
|
as_json.to_json(*args)
|
||||||
end
|
end
|
||||||
end
|
end if defined?(::OpenStruct)
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#frozen_string_literal: false
|
#frozen_string_literal: false
|
||||||
require 'json/version'
|
require 'json/version'
|
||||||
require 'json/generic_object'
|
|
||||||
|
|
||||||
module JSON
|
module JSON
|
||||||
|
autoload :GenericObject, 'json/generic_object'
|
||||||
|
|
||||||
NOT_SET = Object.new.freeze
|
NOT_SET = Object.new.freeze
|
||||||
private_constant :NOT_SET
|
private_constant :NOT_SET
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
#frozen_string_literal: false
|
#frozen_string_literal: false
|
||||||
|
begin
|
||||||
require 'ostruct'
|
require 'ostruct'
|
||||||
|
rescue LoadError
|
||||||
|
warn "JSON::GenericObject requires 'ostruct'. Please install it with `gem install ostruct`."
|
||||||
|
end
|
||||||
|
|
||||||
module JSON
|
module JSON
|
||||||
class GenericObject < OpenStruct
|
class GenericObject < OpenStruct
|
||||||
|
@ -67,5 +71,5 @@ module JSON
|
||||||
def to_json(*a)
|
def to_json(*a)
|
||||||
as_json.to_json(*a)
|
as_json.to_json(*a)
|
||||||
end
|
end
|
||||||
end
|
end if defined?(::OpenStruct)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: false
|
# frozen_string_literal: false
|
||||||
module JSON
|
module JSON
|
||||||
# JSON version
|
# JSON version
|
||||||
VERSION = '2.7.1'
|
VERSION = '2.7.2'
|
||||||
VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
|
VERSION_ARRAY = VERSION.split(/\./).map { |x| x.to_i } # :nodoc:
|
||||||
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
|
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
|
||||||
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
|
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
|
||||||
|
|
|
@ -190,7 +190,7 @@ class JSONAdditionTest < Test::Unit::TestCase
|
||||||
# XXX this won't work; o.foo = { :bar => true }
|
# XXX this won't work; o.foo = { :bar => true }
|
||||||
o.foo = { 'bar' => true }
|
o.foo = { 'bar' => true }
|
||||||
assert_equal o, parse(JSON(o), :create_additions => true)
|
assert_equal o, parse(JSON(o), :create_additions => true)
|
||||||
end
|
end if defined?(::OpenStruct)
|
||||||
|
|
||||||
def test_set
|
def test_set
|
||||||
s = Set.new([:a, :b, :c, :a])
|
s = Set.new([:a, :b, :c, :a])
|
||||||
|
|
|
@ -79,4 +79,4 @@ class JSONGenericObjectTest < Test::Unit::TestCase
|
||||||
ensure
|
ensure
|
||||||
JSON::GenericObject.json_creatable = false
|
JSON::GenericObject.json_creatable = false
|
||||||
end
|
end
|
||||||
end
|
end if defined?(JSON::GenericObject)
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
require_relative 'test_helper'
|
require_relative 'test_helper'
|
||||||
require 'stringio'
|
require 'stringio'
|
||||||
require 'tempfile'
|
require 'tempfile'
|
||||||
|
begin
|
||||||
require 'ostruct'
|
require 'ostruct'
|
||||||
|
rescue LoadError
|
||||||
|
end
|
||||||
begin
|
begin
|
||||||
require 'bigdecimal'
|
require 'bigdecimal'
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
|
@ -412,6 +415,14 @@ EOT
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_parse_object_custom_hash_derived_class
|
||||||
|
res = parse('{"foo":"bar"}', :object_class => SubHash)
|
||||||
|
assert_equal({"foo" => "bar"}, res)
|
||||||
|
assert_equal(SubHash, res.class)
|
||||||
|
assert res.item_set?
|
||||||
|
end
|
||||||
|
|
||||||
|
if defined?(::OpenStruct)
|
||||||
class SubOpenStruct < OpenStruct
|
class SubOpenStruct < OpenStruct
|
||||||
def [](k)
|
def [](k)
|
||||||
__send__(k)
|
__send__(k)
|
||||||
|
@ -427,13 +438,6 @@ EOT
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_parse_object_custom_hash_derived_class
|
|
||||||
res = parse('{"foo":"bar"}', :object_class => SubHash)
|
|
||||||
assert_equal({"foo" => "bar"}, res)
|
|
||||||
assert_equal(SubHash, res.class)
|
|
||||||
assert res.item_set?
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_parse_object_custom_non_hash_derived_class
|
def test_parse_object_custom_non_hash_derived_class
|
||||||
res = parse('{"foo":"bar"}', :object_class => SubOpenStruct)
|
res = parse('{"foo":"bar"}', :object_class => SubOpenStruct)
|
||||||
assert_equal "bar", res.foo
|
assert_equal "bar", res.foo
|
||||||
|
@ -453,6 +457,7 @@ EOT
|
||||||
assert_equal "bar", res.to_hash[:foo]
|
assert_equal "bar", res.to_hash[:foo]
|
||||||
assert_equal(JSON::GenericObject, res.baz.class)
|
assert_equal(JSON::GenericObject, res.baz.class)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_generate_core_subclasses_with_new_to_json
|
def test_generate_core_subclasses_with_new_to_json
|
||||||
obj = SubHash2["foo" => SubHash2["bar" => true]]
|
obj = SubHash2["foo" => SubHash2["bar" => true]]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue