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.
- checksums.yaml +4 -4
- data/CHANGES.md +46 -0
- data/README.md +4 -13
- data/ext/json/ext/generator/generator.c +122 -27
- data/ext/json/ext/generator/generator.h +8 -5
- data/ext/json/ext/parser/parser.c +1828 -2964
- data/ext/json/ext/parser/parser.rl +85 -100
- data/json.gemspec +7 -6
- data/lib/json/add/bigdecimal.rb +37 -8
- data/lib/json/add/complex.rb +28 -5
- data/lib/json/add/date.rb +26 -6
- data/lib/json/add/date_time.rb +25 -8
- data/lib/json/add/exception.rb +24 -6
- data/lib/json/add/ostruct.rb +31 -8
- data/lib/json/add/range.rb +32 -7
- data/lib/json/add/rational.rb +27 -5
- data/lib/json/add/regexp.rb +25 -7
- data/lib/json/add/set.rb +25 -6
- data/lib/json/add/struct.rb +28 -6
- data/lib/json/add/symbol.rb +27 -4
- data/lib/json/add/time.rb +26 -5
- data/lib/json/common.rb +29 -34
- data/lib/json/generic_object.rb +6 -2
- data/lib/json/pure/generator.rb +62 -28
- data/lib/json/pure/parser.rb +1 -1
- data/lib/json/version.rb +1 -1
- data/lib/json.rb +9 -0
- metadata +6 -10
- data/VERSION +0 -1
@@ -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, "
|
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, "
|
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, "
|
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, "
|
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
|
-
|
511
|
+
ruby_xfree(bufferStart);
|
512
512
|
}
|
513
513
|
rb_enc_raise(
|
514
514
|
EXC_ENCODING eParserError,
|
515
|
-
"
|
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
|
-
|
524
|
+
ruby_xfree(bufferStart);
|
525
525
|
}
|
526
526
|
rb_enc_raise(
|
527
527
|
EXC_ENCODING eParserError,
|
528
|
-
"
|
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
|
-
|
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
|
-
|
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
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
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 =
|
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::
|
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, "
|
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
|
-
|
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 =
|
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 = "
|
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' => '
|
61
|
-
'homepage_uri' =>
|
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
|
}
|
data/lib/json/add/bigdecimal.rb
CHANGED
@@ -2,19 +2,36 @@
|
|
2
2
|
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
3
3
|
require 'json'
|
4
4
|
end
|
5
|
-
|
5
|
+
begin
|
6
|
+
require 'bigdecimal'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
6
9
|
|
7
10
|
class BigDecimal
|
8
|
-
|
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
|
-
#
|
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
|
-
#
|
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)
|
data/lib/json/add/complex.rb
CHANGED
@@ -5,14 +5,27 @@ end
|
|
5
5
|
|
6
6
|
class Complex
|
7
7
|
|
8
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
30
|
-
#
|
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
|
data/lib/json/add/date_time.rb
CHANGED
@@ -6,9 +6,7 @@ require 'date'
|
|
6
6
|
|
7
7
|
class DateTime
|
8
8
|
|
9
|
-
#
|
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
|
-
#
|
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
|
-
#
|
43
|
-
#
|
44
|
-
#
|
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
|
data/lib/json/add/exception.rb
CHANGED
@@ -5,16 +5,27 @@ end
|
|
5
5
|
|
6
6
|
class Exception
|
7
7
|
|
8
|
-
#
|
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
|
-
#
|
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
|
-
#
|
27
|
-
#
|
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
|
data/lib/json/add/ostruct.rb
CHANGED
@@ -2,18 +2,34 @@
|
|
2
2
|
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
|
3
3
|
require 'json'
|
4
4
|
end
|
5
|
-
|
5
|
+
begin
|
6
|
+
require 'ostruct'
|
7
|
+
rescue LoadError
|
8
|
+
end
|
6
9
|
|
7
10
|
class OpenStruct
|
8
11
|
|
9
|
-
#
|
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
|
-
#
|
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
|
-
#
|
27
|
-
#
|
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)
|