json 2.6.2 → 2.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -222,14 +222,14 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
222
222
  if (json->allow_nan) {
223
223
  *result = CNaN;
224
224
  } else {
225
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 2);
225
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 2);
226
226
  }
227
227
  }
228
228
  action parse_infinity {
229
229
  if (json->allow_nan) {
230
230
  *result = CInfinity;
231
231
  } else {
232
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p - 8);
232
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p - 7);
233
233
  }
234
234
  }
235
235
  action parse_string {
@@ -245,7 +245,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
245
245
  fexec p + 10;
246
246
  fhold; fbreak;
247
247
  } else {
248
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
248
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
249
249
  }
250
250
  }
251
251
  np = JSON_parse_float(json, fpc, pe, result);
@@ -447,7 +447,7 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
447
447
  if(cs >= JSON_array_first_final) {
448
448
  return p + 1;
449
449
  } else {
450
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
450
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
451
451
  return NULL;
452
452
  }
453
453
  }
@@ -508,11 +508,11 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
508
508
  case 'u':
509
509
  if (pe > stringEnd - 4) {
510
510
  if (bufferSize > MAX_STACK_BUFFER_SIZE) {
511
- free(bufferStart);
511
+ ruby_xfree(bufferStart);
512
512
  }
513
513
  rb_enc_raise(
514
514
  EXC_ENCODING eParserError,
515
- "%u: incomplete unicode character escape sequence at '%s'", __LINE__, p
515
+ "incomplete unicode character escape sequence at '%s'", p
516
516
  );
517
517
  } else {
518
518
  UTF32 ch = unescape_unicode((unsigned char *) ++pe);
@@ -521,11 +521,11 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
521
521
  pe++;
522
522
  if (pe > stringEnd - 6) {
523
523
  if (bufferSize > MAX_STACK_BUFFER_SIZE) {
524
- free(bufferStart);
524
+ ruby_xfree(bufferStart);
525
525
  }
526
526
  rb_enc_raise(
527
527
  EXC_ENCODING eParserError,
528
- "%u: incomplete surrogate pair at '%s'", __LINE__, p
528
+ "incomplete surrogate pair at '%s'", p
529
529
  );
530
530
  }
531
531
  if (pe[0] == '\\' && pe[1] == 'u') {
@@ -566,13 +566,13 @@ static VALUE json_string_unescape(char *string, char *stringEnd, int intern, int
566
566
  result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
567
567
  }
568
568
  if (bufferSize > MAX_STACK_BUFFER_SIZE) {
569
- free(bufferStart);
569
+ ruby_xfree(bufferStart);
570
570
  }
571
571
  # else
572
572
  result = rb_utf8_str_new(bufferStart, (long)(buffer - bufferStart));
573
573
 
574
574
  if (bufferSize > MAX_STACK_BUFFER_SIZE) {
575
- free(bufferStart);
575
+ ruby_xfree(bufferStart);
576
576
  }
577
577
 
578
578
  if (intern) {
@@ -691,8 +691,6 @@ static VALUE convert_encoding(VALUE source)
691
691
  *
692
692
  * Creates a new JSON::Ext::Parser instance for the string _source_.
693
693
  *
694
- * Creates a new JSON::Ext::Parser instance for the string _source_.
695
- *
696
694
  * It will be configured by the _opts_ hash. _opts_ can have the following
697
695
  * keys:
698
696
  *
@@ -721,98 +719,85 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
721
719
  if (json->Vsource) {
722
720
  rb_raise(rb_eTypeError, "already initialized instance");
723
721
  }
724
- #ifdef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
725
722
  rb_scan_args(argc, argv, "1:", &source, &opts);
726
- #else
727
- rb_scan_args(argc, argv, "11", &source, &opts);
728
- #endif
729
723
  if (!NIL_P(opts)) {
730
- #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
731
- opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
732
- if (NIL_P(opts)) {
733
- rb_raise(rb_eArgError, "opts needs to be like a hash");
734
- } else {
735
- #endif
736
- VALUE tmp = ID2SYM(i_max_nesting);
737
- if (option_given_p(opts, tmp)) {
738
- VALUE max_nesting = rb_hash_aref(opts, tmp);
739
- if (RTEST(max_nesting)) {
740
- Check_Type(max_nesting, T_FIXNUM);
741
- json->max_nesting = FIX2INT(max_nesting);
742
- } else {
743
- json->max_nesting = 0;
744
- }
745
- } else {
746
- json->max_nesting = 100;
747
- }
748
- tmp = ID2SYM(i_allow_nan);
749
- if (option_given_p(opts, tmp)) {
750
- json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
751
- } else {
752
- json->allow_nan = 0;
753
- }
754
- tmp = ID2SYM(i_symbolize_names);
755
- if (option_given_p(opts, tmp)) {
756
- json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
757
- } else {
758
- json->symbolize_names = 0;
759
- }
760
- tmp = ID2SYM(i_freeze);
761
- if (option_given_p(opts, tmp)) {
762
- json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
763
- } else {
764
- json->freeze = 0;
765
- }
766
- tmp = ID2SYM(i_create_additions);
767
- if (option_given_p(opts, tmp)) {
768
- json->create_additions = RTEST(rb_hash_aref(opts, tmp));
769
- } else {
770
- json->create_additions = 0;
771
- }
772
- if (json->symbolize_names && json->create_additions) {
773
- rb_raise(rb_eArgError,
774
- "options :symbolize_names and :create_additions cannot be "
775
- " used in conjunction");
776
- }
777
- tmp = ID2SYM(i_create_id);
778
- if (option_given_p(opts, tmp)) {
779
- json->create_id = rb_hash_aref(opts, tmp);
780
- } else {
781
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
782
- }
783
- tmp = ID2SYM(i_object_class);
784
- if (option_given_p(opts, tmp)) {
785
- json->object_class = rb_hash_aref(opts, tmp);
786
- } else {
787
- json->object_class = Qnil;
788
- }
789
- tmp = ID2SYM(i_array_class);
790
- if (option_given_p(opts, tmp)) {
791
- json->array_class = rb_hash_aref(opts, tmp);
792
- } else {
793
- json->array_class = Qnil;
794
- }
795
- tmp = ID2SYM(i_decimal_class);
796
- if (option_given_p(opts, tmp)) {
797
- json->decimal_class = rb_hash_aref(opts, tmp);
798
- } else {
799
- json->decimal_class = Qnil;
800
- }
801
- tmp = ID2SYM(i_match_string);
802
- if (option_given_p(opts, tmp)) {
803
- VALUE match_string = rb_hash_aref(opts, tmp);
804
- json->match_string = RTEST(match_string) ? match_string : Qnil;
805
- } else {
806
- json->match_string = Qnil;
807
- }
808
- #ifndef HAVE_RB_SCAN_ARGS_OPTIONAL_HASH
809
- }
810
- #endif
724
+ VALUE tmp = ID2SYM(i_max_nesting);
725
+ if (option_given_p(opts, tmp)) {
726
+ VALUE max_nesting = rb_hash_aref(opts, tmp);
727
+ if (RTEST(max_nesting)) {
728
+ Check_Type(max_nesting, T_FIXNUM);
729
+ json->max_nesting = FIX2INT(max_nesting);
730
+ } else {
731
+ json->max_nesting = 0;
732
+ }
733
+ } else {
734
+ json->max_nesting = 100;
735
+ }
736
+ tmp = ID2SYM(i_allow_nan);
737
+ if (option_given_p(opts, tmp)) {
738
+ json->allow_nan = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
739
+ } else {
740
+ json->allow_nan = 0;
741
+ }
742
+ tmp = ID2SYM(i_symbolize_names);
743
+ if (option_given_p(opts, tmp)) {
744
+ json->symbolize_names = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
745
+ } else {
746
+ json->symbolize_names = 0;
747
+ }
748
+ tmp = ID2SYM(i_freeze);
749
+ if (option_given_p(opts, tmp)) {
750
+ json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0;
751
+ } else {
752
+ json->freeze = 0;
753
+ }
754
+ tmp = ID2SYM(i_create_additions);
755
+ if (option_given_p(opts, tmp)) {
756
+ json->create_additions = RTEST(rb_hash_aref(opts, tmp));
757
+ } else {
758
+ json->create_additions = 0;
759
+ }
760
+ if (json->symbolize_names && json->create_additions) {
761
+ rb_raise(rb_eArgError,
762
+ "options :symbolize_names and :create_additions cannot be "
763
+ " used in conjunction");
764
+ }
765
+ tmp = ID2SYM(i_create_id);
766
+ if (option_given_p(opts, tmp)) {
767
+ json->create_id = rb_hash_aref(opts, tmp);
768
+ } else {
769
+ json->create_id = rb_funcall(mJSON, i_create_id, 0);
770
+ }
771
+ tmp = ID2SYM(i_object_class);
772
+ if (option_given_p(opts, tmp)) {
773
+ json->object_class = rb_hash_aref(opts, tmp);
774
+ } else {
775
+ json->object_class = Qnil;
776
+ }
777
+ tmp = ID2SYM(i_array_class);
778
+ if (option_given_p(opts, tmp)) {
779
+ json->array_class = rb_hash_aref(opts, tmp);
780
+ } else {
781
+ json->array_class = Qnil;
782
+ }
783
+ tmp = ID2SYM(i_decimal_class);
784
+ if (option_given_p(opts, tmp)) {
785
+ json->decimal_class = rb_hash_aref(opts, tmp);
786
+ } else {
787
+ json->decimal_class = Qnil;
788
+ }
789
+ tmp = ID2SYM(i_match_string);
790
+ if (option_given_p(opts, tmp)) {
791
+ VALUE match_string = rb_hash_aref(opts, tmp);
792
+ json->match_string = RTEST(match_string) ? match_string : Qnil;
793
+ } else {
794
+ json->match_string = Qnil;
795
+ }
811
796
  } else {
812
797
  json->max_nesting = 100;
813
798
  json->allow_nan = 0;
814
799
  json->create_additions = 0;
815
- json->create_id = rb_funcall(mJSON, i_create_id, 0);
800
+ json->create_id = Qnil;
816
801
  json->object_class = Qnil;
817
802
  json->array_class = Qnil;
818
803
  json->decimal_class = Qnil;
@@ -847,7 +832,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
847
832
  *
848
833
  * Parses the current JSON text _source_ and returns the complete data
849
834
  * structure as a result.
850
- * It raises JSON::ParseError if fail to parse.
835
+ * It raises JSON::ParserError if fail to parse.
851
836
  */
852
837
  static VALUE cParser_parse(VALUE self)
853
838
  {
@@ -864,7 +849,7 @@ static VALUE cParser_parse(VALUE self)
864
849
  if (cs >= JSON_first_final && p == pe) {
865
850
  return result;
866
851
  } else {
867
- rb_enc_raise(EXC_ENCODING eParserError, "%u: unexpected token at '%s'", __LINE__, p);
852
+ rb_enc_raise(EXC_ENCODING eParserError, "unexpected token at '%s'", p);
868
853
  return Qnil;
869
854
  }
870
855
  }
data/json.gemspec CHANGED
@@ -1,8 +1,10 @@
1
- # -*- encoding: utf-8 -*-
1
+ version = File.foreach(File.join(__dir__, "lib/json/version.rb")) do |line|
2
+ /^\s*VERSION\s*=\s*'(.*)'/ =~ line and break $1
3
+ end rescue nil
2
4
 
3
5
  Gem::Specification.new do |s|
4
6
  s.name = "json"
5
- s.version = File.read(File.expand_path('../VERSION', __FILE__)).chomp
7
+ s.version = version
6
8
 
7
9
  s.summary = "JSON Implementation for Ruby"
8
10
  s.description = "This is a JSON implementation as a Ruby extension in C."
@@ -17,7 +19,6 @@ Gem::Specification.new do |s|
17
19
  "CHANGES.md",
18
20
  "LICENSE",
19
21
  "README.md",
20
- "VERSION",
21
22
  "ext/json/ext/fbuffer/fbuffer.h",
22
23
  "ext/json/ext/generator/depend",
23
24
  "ext/json/ext/generator/extconf.rb",
@@ -53,12 +54,12 @@ Gem::Specification.new do |s|
53
54
  "lib/json/pure/parser.rb",
54
55
  "lib/json/version.rb",
55
56
  ]
56
- s.homepage = "http://flori.github.com/json"
57
+ s.homepage = "https://flori.github.io/json"
57
58
  s.metadata = {
58
59
  'bug_tracker_uri' => 'https://github.com/flori/json/issues',
59
60
  'changelog_uri' => 'https://github.com/flori/json/blob/master/CHANGES.md',
60
- 'documentation_uri' => 'http://flori.github.io/json/doc/index.html',
61
- 'homepage_uri' => 'http://flori.github.io/json/',
61
+ 'documentation_uri' => 'https://flori.github.io/json/doc/index.html',
62
+ 'homepage_uri' => s.homepage,
62
63
  'source_code_uri' => 'https://github.com/flori/json',
63
64
  'wiki_uri' => 'https://github.com/flori/json/wiki'
64
65
  }
@@ -2,19 +2,36 @@
2
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
3
3
  require 'json'
4
4
  end
5
- defined?(::BigDecimal) or require 'bigdecimal'
5
+ begin
6
+ require 'bigdecimal'
7
+ rescue LoadError
8
+ end
6
9
 
7
10
  class BigDecimal
8
- # Import a JSON Marshalled object.
9
- #
10
- # method used for JSON marshalling support.
11
+
12
+ # See #as_json.
11
13
  def self.json_create(object)
12
14
  BigDecimal._load object['b']
13
15
  end
14
16
 
15
- # Marshal the object to JSON.
17
+ # Methods <tt>BigDecimal#as_json</tt> and +BigDecimal.json_create+ may be used
18
+ # to serialize and deserialize a \BigDecimal object;
19
+ # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
20
+ #
21
+ # \Method <tt>BigDecimal#as_json</tt> serializes +self+,
22
+ # returning a 2-element hash representing +self+:
23
+ #
24
+ # require 'json/add/bigdecimal'
25
+ # x = BigDecimal(2).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"}
26
+ # y = BigDecimal(2.0, 4).as_json # => {"json_class"=>"BigDecimal", "b"=>"36:0.2e1"}
27
+ # z = BigDecimal(Complex(2, 0)).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"}
28
+ #
29
+ # \Method +JSON.create+ deserializes such a hash, returning a \BigDecimal object:
30
+ #
31
+ # BigDecimal.json_create(x) # => 0.2e1
32
+ # BigDecimal.json_create(y) # => 0.2e1
33
+ # BigDecimal.json_create(z) # => 0.2e1
16
34
  #
17
- # method used for JSON marshalling support.
18
35
  def as_json(*)
19
36
  {
20
37
  JSON.create_id => self.class.name,
@@ -22,8 +39,20 @@ class BigDecimal
22
39
  }
23
40
  end
24
41
 
25
- # return the JSON value
42
+ # Returns a JSON string representing +self+:
43
+ #
44
+ # require 'json/add/bigdecimal'
45
+ # puts BigDecimal(2).to_json
46
+ # puts BigDecimal(2.0, 4).to_json
47
+ # puts BigDecimal(Complex(2, 0)).to_json
48
+ #
49
+ # Output:
50
+ #
51
+ # {"json_class":"BigDecimal","b":"27:0.2e1"}
52
+ # {"json_class":"BigDecimal","b":"36:0.2e1"}
53
+ # {"json_class":"BigDecimal","b":"27:0.2e1"}
54
+ #
26
55
  def to_json(*args)
27
56
  as_json.to_json(*args)
28
57
  end
29
- end
58
+ end if defined?(::BigDecimal)
@@ -5,14 +5,27 @@ end
5
5
 
6
6
  class Complex
7
7
 
8
- # Deserializes JSON string by converting Real value <tt>r</tt>, imaginary
9
- # value <tt>i</tt>, to a Complex object.
8
+ # See #as_json.
10
9
  def self.json_create(object)
11
10
  Complex(object['r'], object['i'])
12
11
  end
13
12
 
14
- # Returns a hash, that will be turned into a JSON object and represent this
15
- # object.
13
+ # Methods <tt>Complex#as_json</tt> and +Complex.json_create+ may be used
14
+ # to serialize and deserialize a \Complex object;
15
+ # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
16
+ #
17
+ # \Method <tt>Complex#as_json</tt> serializes +self+,
18
+ # returning a 2-element hash representing +self+:
19
+ #
20
+ # require 'json/add/complex'
21
+ # x = Complex(2).as_json # => {"json_class"=>"Complex", "r"=>2, "i"=>0}
22
+ # y = Complex(2.0, 4).as_json # => {"json_class"=>"Complex", "r"=>2.0, "i"=>4}
23
+ #
24
+ # \Method +JSON.create+ deserializes such a hash, returning a \Complex object:
25
+ #
26
+ # Complex.json_create(x) # => (2+0i)
27
+ # Complex.json_create(y) # => (2.0+4i)
28
+ #
16
29
  def as_json(*)
17
30
  {
18
31
  JSON.create_id => self.class.name,
@@ -21,7 +34,17 @@ class Complex
21
34
  }
22
35
  end
23
36
 
24
- # Stores class name (Complex) along with real value <tt>r</tt> and imaginary value <tt>i</tt> as JSON string
37
+ # Returns a JSON string representing +self+:
38
+ #
39
+ # require 'json/add/complex'
40
+ # puts Complex(2).to_json
41
+ # puts Complex(2.0, 4).to_json
42
+ #
43
+ # Output:
44
+ #
45
+ # {"json_class":"Complex","r":2,"i":0}
46
+ # {"json_class":"Complex","r":2.0,"i":4}
47
+ #
25
48
  def to_json(*args)
26
49
  as_json.to_json(*args)
27
50
  end
data/lib/json/add/date.rb CHANGED
@@ -6,16 +6,29 @@ require 'date'
6
6
 
7
7
  class Date
8
8
 
9
- # Deserializes JSON string by converting Julian year <tt>y</tt>, month
10
- # <tt>m</tt>, day <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> to Date.
9
+ # See #as_json.
11
10
  def self.json_create(object)
12
11
  civil(*object.values_at('y', 'm', 'd', 'sg'))
13
12
  end
14
13
 
15
14
  alias start sg unless method_defined?(:start)
16
15
 
17
- # Returns a hash, that will be turned into a JSON object and represent this
18
- # object.
16
+ # Methods <tt>Date#as_json</tt> and +Date.json_create+ may be used
17
+ # to serialize and deserialize a \Date object;
18
+ # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
19
+ #
20
+ # \Method <tt>Date#as_json</tt> serializes +self+,
21
+ # returning a 2-element hash representing +self+:
22
+ #
23
+ # require 'json/add/date'
24
+ # x = Date.today.as_json
25
+ # # => {"json_class"=>"Date", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0}
26
+ #
27
+ # \Method +JSON.create+ deserializes such a hash, returning a \Date object:
28
+ #
29
+ # Date.json_create(x)
30
+ # # => #<Date: 2023-11-21 ((2460270j,0s,0n),+0s,2299161j)>
31
+ #
19
32
  def as_json(*)
20
33
  {
21
34
  JSON.create_id => self.class.name,
@@ -26,8 +39,15 @@ class Date
26
39
  }
27
40
  end
28
41
 
29
- # Stores class name (Date) with Julian year <tt>y</tt>, month <tt>m</tt>, day
30
- # <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
42
+ # Returns a JSON string representing +self+:
43
+ #
44
+ # require 'json/add/date'
45
+ # puts Date.today.to_json
46
+ #
47
+ # Output:
48
+ #
49
+ # {"json_class":"Date","y":2023,"m":11,"d":21,"sg":2299161.0}
50
+ #
31
51
  def to_json(*args)
32
52
  as_json.to_json(*args)
33
53
  end
@@ -6,9 +6,7 @@ require 'date'
6
6
 
7
7
  class DateTime
8
8
 
9
- # Deserializes JSON string by converting year <tt>y</tt>, month <tt>m</tt>,
10
- # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
11
- # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> to DateTime.
9
+ # See #as_json.
12
10
  def self.json_create(object)
13
11
  args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
14
12
  of_a, of_b = object['of'].split('/')
@@ -23,8 +21,21 @@ class DateTime
23
21
 
24
22
  alias start sg unless method_defined?(:start)
25
23
 
26
- # Returns a hash, that will be turned into a JSON object and represent this
27
- # object.
24
+ # Methods <tt>DateTime#as_json</tt> and +DateTime.json_create+ may be used
25
+ # to serialize and deserialize a \DateTime object;
26
+ # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
27
+ #
28
+ # \Method <tt>DateTime#as_json</tt> serializes +self+,
29
+ # returning a 2-element hash representing +self+:
30
+ #
31
+ # require 'json/add/datetime'
32
+ # x = DateTime.now.as_json
33
+ # # => {"json_class"=>"DateTime", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0}
34
+ #
35
+ # \Method +JSON.create+ deserializes such a hash, returning a \DateTime object:
36
+ #
37
+ # DateTime.json_create(x) # BUG? Raises Date::Error "invalid date"
38
+ #
28
39
  def as_json(*)
29
40
  {
30
41
  JSON.create_id => self.class.name,
@@ -39,9 +50,15 @@ class DateTime
39
50
  }
40
51
  end
41
52
 
42
- # Stores class name (DateTime) with Julian year <tt>y</tt>, month <tt>m</tt>,
43
- # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
44
- # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
53
+ # Returns a JSON string representing +self+:
54
+ #
55
+ # require 'json/add/datetime'
56
+ # puts DateTime.now.to_json
57
+ #
58
+ # Output:
59
+ #
60
+ # {"json_class":"DateTime","y":2023,"m":11,"d":21,"sg":2299161.0}
61
+ #
45
62
  def to_json(*args)
46
63
  as_json.to_json(*args)
47
64
  end
@@ -5,16 +5,27 @@ end
5
5
 
6
6
  class Exception
7
7
 
8
- # Deserializes JSON string by constructing new Exception object with message
9
- # <tt>m</tt> and backtrace <tt>b</tt> serialized with <tt>to_json</tt>
8
+ # See #as_json.
10
9
  def self.json_create(object)
11
10
  result = new(object['m'])
12
11
  result.set_backtrace object['b']
13
12
  result
14
13
  end
15
14
 
16
- # Returns a hash, that will be turned into a JSON object and represent this
17
- # object.
15
+ # Methods <tt>Exception#as_json</tt> and +Exception.json_create+ may be used
16
+ # to serialize and deserialize a \Exception object;
17
+ # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
18
+ #
19
+ # \Method <tt>Exception#as_json</tt> serializes +self+,
20
+ # returning a 2-element hash representing +self+:
21
+ #
22
+ # require 'json/add/exception'
23
+ # x = Exception.new('Foo').as_json # => {"json_class"=>"Exception", "m"=>"Foo", "b"=>nil}
24
+ #
25
+ # \Method +JSON.create+ deserializes such a hash, returning a \Exception object:
26
+ #
27
+ # Exception.json_create(x) # => #<Exception: Foo>
28
+ #
18
29
  def as_json(*)
19
30
  {
20
31
  JSON.create_id => self.class.name,
@@ -23,8 +34,15 @@ class Exception
23
34
  }
24
35
  end
25
36
 
26
- # Stores class name (Exception) with message <tt>m</tt> and backtrace array
27
- # <tt>b</tt> as JSON string
37
+ # Returns a JSON string representing +self+:
38
+ #
39
+ # require 'json/add/exception'
40
+ # puts Exception.new('Foo').to_json
41
+ #
42
+ # Output:
43
+ #
44
+ # {"json_class":"Exception","m":"Foo","b":null}
45
+ #
28
46
  def to_json(*args)
29
47
  as_json.to_json(*args)
30
48
  end
@@ -2,18 +2,34 @@
2
2
  unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
3
3
  require 'json'
4
4
  end
5
- require 'ostruct'
5
+ begin
6
+ require 'ostruct'
7
+ rescue LoadError
8
+ end
6
9
 
7
10
  class OpenStruct
8
11
 
9
- # Deserializes JSON string by constructing new Struct object with values
10
- # <tt>t</tt> serialized by <tt>to_json</tt>.
12
+ # See #as_json.
11
13
  def self.json_create(object)
12
14
  new(object['t'] || object[:t])
13
15
  end
14
16
 
15
- # Returns a hash, that will be turned into a JSON object and represent this
16
- # object.
17
+ # Methods <tt>OpenStruct#as_json</tt> and +OpenStruct.json_create+ may be used
18
+ # to serialize and deserialize a \OpenStruct object;
19
+ # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html].
20
+ #
21
+ # \Method <tt>OpenStruct#as_json</tt> serializes +self+,
22
+ # returning a 2-element hash representing +self+:
23
+ #
24
+ # require 'json/add/ostruct'
25
+ # x = OpenStruct.new('name' => 'Rowdy', :age => nil).as_json
26
+ # # => {"json_class"=>"OpenStruct", "t"=>{:name=>'Rowdy', :age=>nil}}
27
+ #
28
+ # \Method +JSON.create+ deserializes such a hash, returning a \OpenStruct object:
29
+ #
30
+ # OpenStruct.json_create(x)
31
+ # # => #<OpenStruct name='Rowdy', age=nil>
32
+ #
17
33
  def as_json(*)
18
34
  klass = self.class.name
19
35
  klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
@@ -23,9 +39,16 @@ class OpenStruct
23
39
  }
24
40
  end
25
41
 
26
- # Stores class name (OpenStruct) with this struct's values <tt>t</tt> as a
27
- # JSON string.
42
+ # Returns a JSON string representing +self+:
43
+ #
44
+ # require 'json/add/ostruct'
45
+ # puts OpenStruct.new('name' => 'Rowdy', :age => nil).to_json
46
+ #
47
+ # Output:
48
+ #
49
+ # {"json_class":"OpenStruct","t":{'name':'Rowdy',"age":null}}
50
+ #
28
51
  def to_json(*args)
29
52
  as_json.to_json(*args)
30
53
  end
31
- end
54
+ end if defined?(::OpenStruct)