Optimize Symbol generation in strict mode
Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
This commit is contained in:
parent
f865148e19
commit
b4bfbcaddc
@ -991,6 +991,29 @@ static void generate_json_string(FBuffer *buffer, struct generate_json_data *dat
|
|||||||
fbuffer_append_char(buffer, '"');
|
fbuffer_append_char(buffer, '"');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void generate_json_fallback(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj)
|
||||||
|
{
|
||||||
|
VALUE tmp;
|
||||||
|
if (rb_respond_to(obj, i_to_json)) {
|
||||||
|
tmp = rb_funcall(obj, i_to_json, 1, vstate_get(data));
|
||||||
|
Check_Type(tmp, T_STRING);
|
||||||
|
fbuffer_append_str(buffer, tmp);
|
||||||
|
} else {
|
||||||
|
tmp = rb_funcall(obj, i_to_s, 0);
|
||||||
|
Check_Type(tmp, T_STRING);
|
||||||
|
generate_json_string(buffer, data, state, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void generate_json_symbol(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj)
|
||||||
|
{
|
||||||
|
if (state->strict) {
|
||||||
|
generate_json_string(buffer, data, state, rb_sym2str(obj));
|
||||||
|
} else {
|
||||||
|
generate_json_fallback(buffer, data, state, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj)
|
static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj)
|
||||||
{
|
{
|
||||||
fbuffer_append(buffer, "null", 4);
|
fbuffer_append(buffer, "null", 4);
|
||||||
@ -1057,7 +1080,6 @@ static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *d
|
|||||||
|
|
||||||
static void generate_json(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj)
|
static void generate_json(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj)
|
||||||
{
|
{
|
||||||
VALUE tmp;
|
|
||||||
bool as_json_called = false;
|
bool as_json_called = false;
|
||||||
start:
|
start:
|
||||||
if (obj == Qnil) {
|
if (obj == Qnil) {
|
||||||
@ -1071,6 +1093,8 @@ start:
|
|||||||
generate_json_fixnum(buffer, data, state, obj);
|
generate_json_fixnum(buffer, data, state, obj);
|
||||||
} else if (RB_FLONUM_P(obj)) {
|
} else if (RB_FLONUM_P(obj)) {
|
||||||
generate_json_float(buffer, data, state, obj);
|
generate_json_float(buffer, data, state, obj);
|
||||||
|
} else if (RB_STATIC_SYM_P(obj)) {
|
||||||
|
generate_json_symbol(buffer, data, state, obj);
|
||||||
} else {
|
} else {
|
||||||
goto general;
|
goto general;
|
||||||
}
|
}
|
||||||
@ -1092,6 +1116,9 @@ start:
|
|||||||
if (klass != rb_cString) goto general;
|
if (klass != rb_cString) goto general;
|
||||||
generate_json_string(buffer, data, state, obj);
|
generate_json_string(buffer, data, state, obj);
|
||||||
break;
|
break;
|
||||||
|
case T_SYMBOL:
|
||||||
|
generate_json_symbol(buffer, data, state, obj);
|
||||||
|
break;
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
if (klass != rb_cFloat) goto general;
|
if (klass != rb_cFloat) goto general;
|
||||||
generate_json_float(buffer, data, state, obj);
|
generate_json_float(buffer, data, state, obj);
|
||||||
@ -1110,14 +1137,8 @@ start:
|
|||||||
} else {
|
} else {
|
||||||
raise_generator_error(obj, "%"PRIsVALUE" not allowed in JSON", CLASS_OF(obj));
|
raise_generator_error(obj, "%"PRIsVALUE" not allowed in JSON", CLASS_OF(obj));
|
||||||
}
|
}
|
||||||
} else if (rb_respond_to(obj, i_to_json)) {
|
|
||||||
tmp = rb_funcall(obj, i_to_json, 1, vstate_get(data));
|
|
||||||
Check_Type(tmp, T_STRING);
|
|
||||||
fbuffer_append_str(buffer, tmp);
|
|
||||||
} else {
|
} else {
|
||||||
tmp = rb_funcall(obj, i_to_s, 0);
|
generate_json_fallback(buffer, data, state, obj);
|
||||||
Check_Type(tmp, T_STRING);
|
|
||||||
generate_json_string(buffer, data, state, tmp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,13 @@ class Symbol
|
|||||||
#
|
#
|
||||||
# # {"json_class":"Symbol","s":"foo"}
|
# # {"json_class":"Symbol","s":"foo"}
|
||||||
#
|
#
|
||||||
def to_json(*a)
|
def to_json(state = nil, *a)
|
||||||
as_json.to_json(*a)
|
state = ::JSON::State.from_state(state)
|
||||||
|
if state.strict?
|
||||||
|
super
|
||||||
|
else
|
||||||
|
as_json.to_json(state, *a)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# See #as_json.
|
# See #as_json.
|
||||||
|
@ -86,6 +86,10 @@ class JSONGeneratorTest < Test::Unit::TestCase
|
|||||||
|
|
||||||
assert_equal '42', dump(42, strict: true)
|
assert_equal '42', dump(42, strict: true)
|
||||||
assert_equal 'true', dump(true, strict: true)
|
assert_equal 'true', dump(true, strict: true)
|
||||||
|
|
||||||
|
assert_equal '"hello"', dump(:hello, strict: true)
|
||||||
|
assert_equal '"hello"', :hello.to_json(strict: true)
|
||||||
|
assert_equal '"World"', "World".to_json(strict: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_generate_pretty
|
def test_generate_pretty
|
||||||
|
Loading…
x
Reference in New Issue
Block a user