json 2.6.2 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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)