diff --git a/Gemfile b/Gemfile index 731f95e..c0a7505 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,14 @@ source 'https://rubygems.org' gem 'json' gem 'json_pure' -gem 'yajl-ruby', :require => 'yajl' gem 'active_support' -gem 'oj' + +platforms :ruby do + gem 'yajl-ruby', :require => 'yajl' + gem 'oj' +end + +platforms :jruby do + gem 'jrjackson' +end diff --git a/lib/rufus/json.rb b/lib/rufus/json.rb index d78fa24..6bd911d 100644 --- a/lib/rufus/json.rb +++ b/lib/rufus/json.rb @@ -94,6 +94,19 @@ module Json ::Oj::ParseError } } + # https://github.com/guyboertje/jrjackson + # + JRJACKSON = { + :encode => lambda { |o, opts| + fix_raw_value(::JrJackson::Json.dump(syms_to_s(o))) }, + :pretty_encode => lambda { |o| + fix_raw_value(::JrJackson::Json.dump(syms_to_s(o))) }, + :decode => lambda { |s| + ::JrJackson::Json.load(s) }, + :error => lambda { + ::JrJackson::ParseError } + } + # The "raise an exception because there's no backend" backend # NONE = { @@ -134,7 +147,9 @@ def self.load_backend(*order) # def self.detect_backend - @backend = if defined?(::Oj) + @backend = if defined?(::JrJackson) + JRJACKSON + elsif defined?(::Oj) OJ elsif defined?(::Yajl) YAJL @@ -161,7 +176,7 @@ def self.has_backend? # def self.backend - %w[ yajl json active oj none ].find { |b| + %w[ yajl json active oj jrjackson none ].find { |b| Rufus::Json.const_get(b.upcase) == @backend }.to_sym end @@ -177,7 +192,7 @@ def self.backend=(b) 'yajl' => YAJL, 'yajl-ruby' => YAJL, 'json' => JSON, 'json-pure' => JSON, 'active' => ACTIVE, 'active-support' => ACTIVE, - 'oj' => OJ, 'none' => NONE + 'oj' => OJ, 'jrjackson' => JRJACKSON, 'none' => NONE }[b.to_s.gsub(/[_\/]/, '-')] if b.is_a?(String) or b.is_a?(Symbol) @backend = b @@ -253,6 +268,20 @@ def self.syms_to_s(o) o.inject({}) { |h, (k, v)| h[k.to_s] = syms_to_s(v); h } end + # Used to handle parsers that do not support raw value encoding + # (i.e. JrJackson) + def self.fix_raw_value(o) + case o + when FalseClass, TrueClass, Fixnum, Float + o.to_s + when NilClass + 'null' + else + o + end + + end + # Wraps parser errors during decode # class ParserError < StandardError; end diff --git a/rufus-json.gemspec b/rufus-json.gemspec index 4ba5ada..ba55d6b 100644 --- a/rufus-json.gemspec +++ b/rufus-json.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |s| s.summary = 'One interface to various JSON ruby libs, with a preference for yajl.' s.description = %{ -One interface to various JSON ruby libs (yajl, oj, json, json_pure, json-jruby, active_support). Has a preference for yajl. +One interface to various JSON ruby libs (yajl, oj, jrjackson, json, json_pure, json-jruby, active_support). Has a preference for yajl. }.strip #s.files = `git ls-files`.split("\n") @@ -26,6 +26,7 @@ One interface to various JSON ruby libs (yajl, oj, json, json_pure, json-jruby, '*.gemspec', '*.txt', '*.rdoc', '*.md' ] + #s.add_development_dependency 'jrjackson' #s.add_development_dependency 'oj' #s.add_development_dependency 'json' #s.add_development_dependency 'json_pure' diff --git a/test/backend_test.rb b/test/backend_test.rb index 63126fe..9cb3b24 100644 --- a/test/backend_test.rb +++ b/test/backend_test.rb @@ -59,8 +59,13 @@ def test_load_backend r = Rufus::Json.load_backend - assert_equal 'yajl', r - assert_equal :yajl, Rufus::Json.backend + if RUBY_PLATFORM == 'ruby' + assert_equal 'yajl', r + assert_equal :yajl, Rufus::Json.backend + elsif RUBY_PLATFORM == 'jruby' + assert_equal 'active_support', r + assert_equal :active, Rufus::Json.backend + end end def test_load_backend_with_different_order diff --git a/test/do_test.rb b/test/do_test.rb index a483695..9e564e4 100644 --- a/test/do_test.rb +++ b/test/do_test.rb @@ -128,7 +128,7 @@ def test_pretty_encode s = Rufus::Json.pretty_encode( { 'a' => 'b', 'e' => [ 1, 2, 3 ], 'c' => { 'd' => true } }) - assert(s.index("\n")) if JSON_LIB != 'active_support' + assert(s.index("\n")) if JSON_LIB != 'active_support' && JSON_LIB != 'jrjackson' #no pretty encoding supported end end diff --git a/test/test.rb b/test/test.rb index 3f848d5..960b400 100644 --- a/test/test.rb +++ b/test/test.rb @@ -25,6 +25,7 @@ def do_test(command) LIBS = %w[ json active_support json/pure ] LIBS.concat %w[ yajl oj ] if RUBY_PLATFORM != 'java' +LIBS.concat %w[ jrjackson ] if RUBY_PLATFORM == 'java' LIBS.each do |lib| do_test "export JSON=#{lib}; #{R} #{P}/do_test.rb"