diff --git a/ext/yajl_ext.c b/ext/yajl_ext.c index 1cd26e15..1408b0a8 100644 --- a/ext/yajl_ext.c +++ b/ext/yajl_ext.c @@ -173,7 +173,10 @@ void yajl_encode_part(void * wrapper, VALUE obj, VALUE io) { status = yajl_gen_string(w->encoder, (const unsigned char *)cptr, len); break; default: - if (rb_respond_to(obj, intern_to_json)) { + if (rb_respond_to(obj, intern_as_json)) { + obj = rb_funcall(obj, intern_as_json, 0); + yajl_encode_part(w, obj, io); + } else if (rb_respond_to(obj, intern_to_json)) { str = rb_funcall(obj, intern_to_json, 0); cptr = RSTRING_PTR(str); len = RSTRING_LEN(str); @@ -886,6 +889,7 @@ void Init_yajl_ext() { intern_to_json = rb_intern("to_json"); intern_to_sym = rb_intern("to_sym"); intern_has_key = rb_intern("has_key?"); + intern_as_json = rb_intern("as_json"); sym_allow_comments = ID2SYM(rb_intern("allow_comments")); sym_check_utf8 = ID2SYM(rb_intern("check_utf8")); diff --git a/ext/yajl_ext.h b/ext/yajl_ext.h index 17598e64..ae3e7e68 100644 --- a/ext/yajl_ext.h +++ b/ext/yajl_ext.h @@ -49,7 +49,7 @@ int utf8Encoding; static VALUE cParseError, cEncodeError, mYajl, cParser, cEncoder; static ID intern_io_read, intern_call, intern_keys, intern_to_s, - intern_to_json, intern_has_key, intern_to_sym; + intern_to_json, intern_has_key, intern_to_sym, intern_as_json; static ID sym_allow_comments, sym_check_utf8, sym_pretty, sym_indent, sym_terminator, sym_symbolize_keys; #define GetParser(obj, sval) (sval = (yajl_parser_wrapper*)DATA_PTR(obj)); diff --git a/spec/encoding/encoding_spec.rb b/spec/encoding/encoding_spec.rb index 20990460..3b383b8c 100644 --- a/spec/encoding/encoding_spec.rb +++ b/spec/encoding/encoding_spec.rb @@ -3,7 +3,13 @@ class Dummy2 def to_json - "hawtness".dump + "{\"hawtness\":true}" + end +end + +class Dummy3 + def as_json + {:hawtness => true} end end @@ -152,7 +158,12 @@ def to_json it "should check for and call #to_json if it exists on custom objects" do d = Dummy2.new - Yajl::Encoder.encode({:foo => d}).should eql('{"foo":"hawtness"}') + Yajl::Encoder.encode({:foo => d}).should eql('{"foo":{"hawtness":true}}') + end + + it "should check for and call #as_json if it exists on custom objects" do + d = Dummy3.new + Yajl::Encoder.encode(d).should eql('{"hawtness":true}') end it "should encode a hash where the key and value can be symbols" do