diff options
author | Étienne Barrié <[email protected]> | 2025-01-20 11:12:09 +0100 |
---|---|---|
committer | Jean Boussier <[email protected]> | 2025-01-20 14:20:55 +0100 |
commit | e8676cada82ed9947502b416eaa948258a62d7b9 (patch) | |
tree | 05dbf50a935789222337d04b1edc230b296de02b | |
parent | ba44e92573f5fdd23d29cfb49d8afe78287d5f79 (diff) |
[ruby/json] Introduce JSON::Fragment
https://github.com/ruby/json/commit/9e3500f345
Co-authored-by: Jean Boussier <[email protected]>
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/12602
-rw-r--r-- | ext/json/generator/generator.c | 18 | ||||
-rw-r--r-- | ext/json/lib/json/common.rb | 6 | ||||
-rwxr-xr-x | test/json/json_generator_test.rb | 5 |
3 files changed, 28 insertions, 1 deletions
diff --git a/ext/json/generator/generator.c b/ext/json/generator/generator.c index 5006b7853e..62c0c420cc 100644 --- a/ext/json/generator/generator.c +++ b/ext/json/generator/generator.c @@ -27,7 +27,7 @@ typedef struct JSON_Generator_StateStruct { #define RB_UNLIKELY(cond) (cond) #endif -static VALUE mJSON, cState, mString_Extend, eGeneratorError, eNestingError, Encoding_UTF_8; +static VALUE mJSON, cState, cFragment, mString_Extend, eGeneratorError, eNestingError, Encoding_UTF_8; static ID i_to_s, i_to_json, i_new, i_pack, i_unpack, i_create_id, i_extend, i_encode; static ID sym_indent, sym_space, sym_space_before, sym_object_nl, sym_array_nl, sym_max_nesting, sym_allow_nan, @@ -68,6 +68,7 @@ static void generate_json_integer(FBuffer *buffer, struct generate_json_data *da static void generate_json_fixnum(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj); static void generate_json_bignum(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj); static void generate_json_float(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj); +static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj); static int usascii_encindex, utf8_encindex, binary_encindex; @@ -971,6 +972,13 @@ static void generate_json_float(FBuffer *buffer, struct generate_json_data *data fbuffer_append_str(buffer, tmp); } +static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj) +{ + VALUE fragment = RSTRUCT_GET(obj, 0); + Check_Type(fragment, T_STRING); + fbuffer_append_str(buffer, fragment); +} + static void generate_json(FBuffer *buffer, struct generate_json_data *data, JSON_Generator_State *state, VALUE obj) { VALUE tmp; @@ -1010,6 +1018,10 @@ static void generate_json(FBuffer *buffer, struct generate_json_data *data, JSON if (klass != rb_cFloat) goto general; generate_json_float(buffer, data, state, obj); break; + case T_STRUCT: + if (klass != cFragment) goto general; + generate_json_fragment(buffer, data, state, obj); + break; default: general: if (state->strict) { @@ -1546,6 +1558,10 @@ void Init_generator(void) rb_require("json/common"); mJSON = rb_define_module("JSON"); + + rb_global_variable(&cFragment); + cFragment = rb_const_get(mJSON, rb_intern("Fragment")); + VALUE mExt = rb_define_module_under(mJSON, "Ext"); VALUE mGenerator = rb_define_module_under(mExt, "Generator"); diff --git a/ext/json/lib/json/common.rb b/ext/json/lib/json/common.rb index 3c85ef0655..8a000aa359 100644 --- a/ext/json/lib/json/common.rb +++ b/ext/json/lib/json/common.rb @@ -167,6 +167,12 @@ module JSON # system. Usually this means that the iconv library is not installed. class MissingUnicodeSupport < JSONError; end + Fragment = Struct.new(:json) do + def to_json(state = nil) + json + end + end + module_function # :call-seq: diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb index 8dd3913d62..824de2c1a6 100755 --- a/test/json/json_generator_test.rb +++ b/test/json/json_generator_test.rb @@ -661,4 +661,9 @@ class JSONGeneratorTest < Test::Unit::TestCase def test_nonutf8_encoding assert_equal("\"5\u{b0}\"", "5\xb0".dup.force_encoding(Encoding::ISO_8859_1).to_json) end + + def test_fragment + fragment = JSON::Fragment.new(" 42") + assert_equal '{"number": 42}', JSON.generate({ number: fragment }) + end end |