Skip to content

Commit 4ff4789

Browse files
committed
Make symbolizing names an option
1 parent 100e302 commit 4ff4789

File tree

3 files changed

+35
-19
lines changed

3 files changed

+35
-19
lines changed

ext/fast_jsonparser/fast_jsonparser.cpp

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ VALUE rb_eFastJsonparserUnknownError, rb_eFastJsonparserParseError;
77
using namespace simdjson;
88

99
// Convert tape to Ruby's Object
10-
static VALUE make_ruby_object(dom::element element)
10+
static VALUE make_ruby_object(dom::element element, bool symbolize_names)
1111
{
1212
switch (element.type())
1313
{
@@ -16,7 +16,7 @@ static VALUE make_ruby_object(dom::element element)
1616
VALUE ary = rb_ary_new();
1717
for (dom::element x : element)
1818
{
19-
VALUE e = make_ruby_object(x);
19+
VALUE e = make_ruby_object(x, symbolize_names);
2020
rb_ary_push(ary, e);
2121
}
2222
return ary;
@@ -27,9 +27,12 @@ static VALUE make_ruby_object(dom::element element)
2727
for (dom::key_value_pair field : dom::object(element))
2828
{
2929
std::string_view view(field.key);
30-
VALUE k = rb_intern_str(rb_utf8_str_new(view.data(), view.size()));
31-
VALUE v = make_ruby_object(field.value);
32-
rb_hash_aset(hash, ID2SYM(k), v);
30+
VALUE k = rb_utf8_str_new(view.data(), view.size());
31+
if (symbolize_names) {
32+
k = ID2SYM(rb_intern_str(k));
33+
}
34+
VALUE v = make_ruby_object(field.value, symbolize_names);
35+
rb_hash_aset(hash, k, v);
3336
}
3437
return hash;
3538
}
@@ -63,7 +66,7 @@ static VALUE make_ruby_object(dom::element element)
6366
rb_raise(rb_eException, "[BUG] must not happen");
6467
}
6568

66-
static VALUE rb_fast_jsonparser_parse(VALUE self, VALUE arg)
69+
static VALUE rb_fast_jsonparser_parse(VALUE self, VALUE arg, VALUE symbolize_names)
6770
{
6871
Check_Type(arg, T_STRING);
6972

@@ -73,10 +76,10 @@ static VALUE rb_fast_jsonparser_parse(VALUE self, VALUE arg)
7376
{
7477
rb_raise(rb_eFastJsonparserParseError, "%s", error_message(error));
7578
}
76-
return make_ruby_object(doc);
79+
return make_ruby_object(doc, RTEST(symbolize_names));
7780
}
7881

79-
static VALUE rb_fast_jsonparser_load(VALUE self, VALUE arg)
82+
static VALUE rb_fast_jsonparser_load(VALUE self, VALUE arg, VALUE symbolize_names)
8083
{
8184
Check_Type(arg, T_STRING);
8285

@@ -86,10 +89,10 @@ static VALUE rb_fast_jsonparser_load(VALUE self, VALUE arg)
8689
{
8790
rb_raise(rb_eFastJsonparserParseError, "%s", error_message(error));
8891
}
89-
return make_ruby_object(doc);
92+
return make_ruby_object(doc, RTEST(symbolize_names));
9093
}
9194

92-
static VALUE rb_fast_jsonparser_load_many(VALUE self, VALUE arg, VALUE batch_size)
95+
static VALUE rb_fast_jsonparser_load_many(VALUE self, VALUE arg, VALUE symbolize_names, VALUE batch_size)
9396
{
9497
Check_Type(arg, T_STRING);
9598
Check_Type(batch_size, T_FIXNUM);
@@ -104,7 +107,7 @@ static VALUE rb_fast_jsonparser_load_many(VALUE self, VALUE arg, VALUE batch_siz
104107

105108
for (dom::element doc : docs)
106109
{
107-
rb_yield(make_ruby_object(doc));
110+
rb_yield(make_ruby_object(doc, RTEST(symbolize_names)));
108111
}
109112

110113
return Qnil;
@@ -120,14 +123,13 @@ extern "C"
120123
{
121124
VALUE rb_mFastJsonparser = rb_const_get(rb_cObject, rb_intern("FastJsonparser"));
122125

123-
rb_define_module_function(rb_mFastJsonparser, "parse", reinterpret_cast<VALUE (*)(...)>(rb_fast_jsonparser_parse), 1);
124-
rb_define_module_function(rb_mFastJsonparser, "load", reinterpret_cast<VALUE (*)(...)>(rb_fast_jsonparser_load), 1);
125-
rb_define_module_function(rb_mFastJsonparser, "_load_many", reinterpret_cast<VALUE (*)(...)>(rb_fast_jsonparser_load_many), 2);
126+
rb_define_module_function(rb_mFastJsonparser, "_parse", reinterpret_cast<VALUE (*)(...)>(rb_fast_jsonparser_parse), 2);
127+
rb_define_module_function(rb_mFastJsonparser, "_load", reinterpret_cast<VALUE (*)(...)>(rb_fast_jsonparser_load), 2);
128+
rb_define_module_function(rb_mFastJsonparser, "_load_many", reinterpret_cast<VALUE (*)(...)>(rb_fast_jsonparser_load_many), 3);
126129

127130
rb_eFastJsonparserParseError = rb_const_get(rb_mFastJsonparser, rb_intern("ParseError"));
128131
rb_global_variable(&rb_eFastJsonparserParseError);
129132
rb_eFastJsonparserUnknownError = rb_const_get(rb_mFastJsonparser, rb_intern("UnknownError"));
130133
rb_global_variable(&rb_eFastJsonparserUnknownError);
131-
132134
}
133135
}

lib/fast_jsonparser.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,16 @@ module FastJsonparser
1111
DEFAULT_BATCH_SIZE = 1_000_000 # from include/simdjson/dom/parser.h
1212

1313
class << self
14-
def load_many(source, batch_size: DEFAULT_BATCH_SIZE, &block)
15-
_load_many(source, batch_size, &block)
14+
def parse(source, symbolize_names: true)
15+
_parse(source, symbolize_names)
16+
end
17+
18+
def load(source, symbolize_names: true)
19+
_load(source, symbolize_names)
20+
end
21+
22+
def load_many(source, symbolize_names: true, batch_size: DEFAULT_BATCH_SIZE, &block)
23+
_load_many(source, symbolize_names, batch_size, &block)
1624
rescue UnknownError => error
1725
case error.message
1826
when "This parser can't support a document that big"
@@ -23,6 +31,6 @@ def load_many(source, batch_size: DEFAULT_BATCH_SIZE, &block)
2331
end
2432

2533
require "fast_jsonparser/fast_jsonparser" # loads cpp extension
26-
private :_load_many
34+
private :_parse, :_load, :_load_many
2735
end
2836
end

test/fast_jsonparser_test.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
require "test_helper"
24
require 'tempfile'
35
require 'json'
@@ -13,9 +15,13 @@ def test_string_encoding
1315
end
1416

1517
def test_symbols_encoding
16-
hash = FastJsonparser.parse('{"École": 1}')
18+
hash = FastJsonparser.parse('{"École": 1}', symbolize_names: true)
1719
assert_includes hash, :"École"
1820
assert_equal Encoding::UTF_8, hash.keys.first.encoding
21+
22+
hash = FastJsonparser.parse('{"École": 1}', symbolize_names: false)
23+
assert_includes hash, "École"
24+
assert_equal Encoding::UTF_8, hash.keys.first.encoding
1925
end
2026

2127
def test_json_load_from_file_is_working

0 commit comments

Comments
 (0)