RFC7159 7159
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 +7 -0
- data/.gitignore +61 -0
- data/.rspec +4 -0
- data/.yardopts +2 -0
- data/Gemfile +46 -0
- data/LICENSE.txt +40 -0
- data/README.txt +899 -0
- data/RFC7159 +899 -0
- data/RFC7159.gemspec +85 -0
- data/Rakefile +82 -0
- data/lib/RFC7159.rb +80 -0
- data/lib/RFC7159/array.rb +134 -0
- data/lib/RFC7159/dumper.rb +231 -0
- data/lib/RFC7159/false.rb +79 -0
- data/lib/RFC7159/null.rb +79 -0
- data/lib/RFC7159/number.rb +149 -0
- data/lib/RFC7159/object.rb +140 -0
- data/lib/RFC7159/parser.ry +267 -0
- data/lib/RFC7159/string.rb +221 -0
- data/lib/RFC7159/true.rb +79 -0
- data/lib/RFC7159/value.rb +96 -0
- data/lib/RFC7159/version.rb +48 -0
- data/spec/RFC7159_spec.rb +275 -0
- data/spec/acceptance/README.txt +66 -0
- data/spec/acceptance/invalid/0001-ws/0001-verical-tab.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0002-null.txt +0 -0
- data/spec/acceptance/invalid/0001-ws/0003-space-in-number-1.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0004-space-in-number-2.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0005-space-in-number-3.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0006-space-in-number-4.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0007-space-in-number-5.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0008-space-in-number-6.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0009-space-in-literal.txt +1 -0
- data/spec/acceptance/invalid/0001-ws/0010-Unicode-LINE_SEPARATOR.txt +1 -0
- data/spec/acceptance/invalid/0002-comments/0001-C-style.txt +1 -0
- data/spec/acceptance/invalid/0002-comments/0002-C-plusplus-style.txt +2 -0
- data/spec/acceptance/invalid/0002-comments/0003-sh-style.txt +2 -0
- data/spec/acceptance/invalid/0002-comments/0004-python-docstring.txt +3 -0
- data/spec/acceptance/invalid/0002-comments/0005-SQL-style.txt +2 -0
- data/spec/acceptance/invalid/0002-comments/0006-BASIC-style.txt +2 -0
- data/spec/acceptance/invalid/0003-literals/0001-FALSE.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0002-NULL.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0003-TRUE.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0004-NUL.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0005-nil.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0006-undef.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0007-modifier.txt +1 -0
- data/spec/acceptance/invalid/0003-literals/0008-undefined.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0001-omit-zero.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0002-minus-dot.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0003-missing-frac.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0004-missing-exp.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0005-octal.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0006-hexadecimal.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0007-comma.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0008-perl-underscore.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0009-NaN.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0010-Inf.txt +1 -0
- data/spec/acceptance/invalid/0004-numbers/0011-Infinity.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0000-NUL.txt +0 -0
- data/spec/acceptance/invalid/0005-strings/0001-not-terminated.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0002-single-quote.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0003-back-quote.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0004-carriage-return.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0005-line-feed.txt +2 -0
- data/spec/acceptance/invalid/0005-strings/0006-unknown-escape-a.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0007-unknown-escape-perl-style.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0008-unknown-escape-C-style.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0009-unknown-escape-ruby-style.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0010-escape-too-short.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0011-C-string-concat.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0012-perl-string-concat.txt +1 -0
- data/spec/acceptance/invalid/0005-strings/0013-Java-string-concat.txt +1 -0
- data/spec/acceptance/invalid/0006-encodings/0001-CESU-8.txt +1 -0
- data/spec/acceptance/invalid/0006-encodings/0002-Windows-31J.txt +1 -0
- data/spec/acceptance/invalid/0006-encodings/0003-EBCDIC.txt +1 -0
- data/spec/acceptance/invalid/0006-encodings/0004-overlong-utf8.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0001-lacks-open.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0002-lacks-close.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0003-interleaving-parens.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0004-dangling-comma.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0005-missing-comma.txt +1 -0
- data/spec/acceptance/invalid/0007-arrays/0006-colon-instead-of-comma.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0001-key-missing.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0002-value-missing.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0003-true-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0004-false-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0005-null-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0006-numeric-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0007-array-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0008-hash-key.txt +1 -0
- data/spec/acceptance/invalid/0008-hashes/0009-key-not-escaped.txt +4 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0001-JSONP.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0002-new-Array.txt +3 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0003-new-Date.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0004-new-Error.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0005-Math.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0006-regular-expression.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0007-function.txt +7 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0008-this.txt +1 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0009-plusplus.txt +3 -0
- data/spec/acceptance/invalid/0009-javascriptisms/0010-ternary-operator.txt +1 -0
- data/spec/acceptance/valid/0001-ws/0001-space.json +1 -0
- data/spec/acceptance/valid/0001-ws/0002-tab.json +1 -0
- data/spec/acceptance/valid/0001-ws/0003-lf.json +1 -0
- data/spec/acceptance/valid/0001-ws/0004-cr.json +1 -0
- data/spec/acceptance/valid/0001-ws/0005-before.json +1 -0
- data/spec/acceptance/valid/0001-ws/0006-after.json +1 -0
- data/spec/acceptance/valid/0001-ws/0007-around-comma.json +3 -0
- data/spec/acceptance/valid/0001-ws/0008-around-colon.json +3 -0
- data/spec/acceptance/valid/0002-bare-values/0001-false.json +1 -0
- data/spec/acceptance/valid/0002-bare-values/0002-null.json +1 -0
- data/spec/acceptance/valid/0002-bare-values/0003-true.json +1 -0
- data/spec/acceptance/valid/0002-bare-values/0004-number.json +1 -0
- data/spec/acceptance/valid/0002-bare-values/0005-string.json +1 -0
- data/spec/acceptance/valid/0003-literals/0001-false.json +1 -0
- data/spec/acceptance/valid/0003-literals/0002-null.json +1 -0
- data/spec/acceptance/valid/0003-literals/0003-true.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0000-zero.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0001-one.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0002-two.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0003-three.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0004-four.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0005-five.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0006-six.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0007-seven.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0008-eight.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0009-nine.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0010-ten.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0011-minus.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0012-fraction.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0013-exponent.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0014-exponent-minus.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0015-exponent-plus.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0016-complex.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0017-DBL_MAX.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0018-DBL_MIN.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0019-subnormal-number.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0020-1E400.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0021-pi.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0022-UINT32_MAX.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0023-UINT64_MAX.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0024-INT64_MIN.json +1 -0
- data/spec/acceptance/valid/0004-numbers/0025-high-resolution-zero.json +1 -0
- data/spec/acceptance/valid/0005-strings/0001-empty.json +1 -0
- data/spec/acceptance/valid/0005-strings/0002-basic-latin.json +1 -0
- data/spec/acceptance/valid/0005-strings/0003-escapes.json +1 -0
- data/spec/acceptance/valid/0005-strings/0004-raw-unicode.json +1 -0
- data/spec/acceptance/valid/0005-strings/0005-escaped-unicode.json +1 -0
- data/spec/acceptance/valid/0005-strings/0006-escaped-NUL.json +1 -0
- data/spec/acceptance/valid/0005-strings/0007-escaped-invalid-unicode-still-valid-as-json.json +1 -0
- data/spec/acceptance/valid/0005-strings/0008-ruby-json-gem-cant-handle-this.json +1 -0
- data/spec/acceptance/valid/0005-strings/0009-unescaped-invalid-javascript-still-valid-as-json.json +1 -0
- data/spec/acceptance/valid/0006-m17n/0001-genesis.json +6 -0
- data/spec/acceptance/valid/0006-m17n/0002-heart-sutra.json +5 -0
- data/spec/acceptance/valid/0006-m17n/0003-escaped-valid-surrogate-pair.json +1 -0
- data/spec/acceptance/valid/0006-m17n/0004-unescaped-valid-supplementary-multilingual-plane.json +1 -0
- data/spec/acceptance/valid/0007-arrays/0000-empty.json +1 -0
- data/spec/acceptance/valid/0007-arrays/0001-one-element.json +1 -0
- data/spec/acceptance/valid/0007-arrays/0002-multiple-elements.json +33 -0
- data/spec/acceptance/valid/0007-arrays/0003-various-types.json +1 -0
- data/spec/acceptance/valid/0007-arrays/0004-nested.json +17 -0
- data/spec/acceptance/valid/0008-hashes/0000-empty.json +1 -0
- data/spec/acceptance/valid/0008-hashes/0001-onekey.json +1 -0
- data/spec/acceptance/valid/0008-hashes/0002-many-keys.json +5 -0
- data/spec/acceptance/valid/0008-hashes/0003-empty-key.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0004-true-value.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0005-false-value.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0006-null-value.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0007-string-value.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0008-numeric-value.json +3 -0
- data/spec/acceptance/valid/0008-hashes/0009-array-value.json +8 -0
- data/spec/acceptance/valid/0008-hashes/0010-hash-value.json +20 -0
- data/spec/acceptance/valid/0008-hashes/0011-duplicate-key-in-different-representations.json +4 -0
- data/spec/acceptance/valid/0008-hashes/0011-duplicate-key.json +4 -0
- data/spec/spec_helper.rb +54 -0
- metadata +520 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
#! /your/favourite/path/to/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2014 Urabe, Shyouhei. All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# - Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# - Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in
|
14
|
+
# the documentation and/or other materials provided with the
|
15
|
+
# distribution.
|
16
|
+
#
|
17
|
+
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
18
|
+
# names of specific contributors, may be used to endorse or promote
|
19
|
+
# products derived from this software without specific prior written
|
20
|
+
# permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
|
34
|
+
# The false, as defined in RFC7159 section 3.
|
35
|
+
class RFC7159::False < RFC7159::Value
|
36
|
+
|
37
|
+
# Parse the AST from parser, and convert into corrsponding value.
|
38
|
+
# @param [::Array] ast the AST, generated by the parser
|
39
|
+
# @return [False] evaluated instance
|
40
|
+
# @raise [ArgumentError] malformed input
|
41
|
+
def self.from_ast ast
|
42
|
+
raise ArgumentError "garbage included: #{ast.inspect}" if ast.length > 1
|
43
|
+
raise ArgumentError "not a false: #{ast.inspect}" if ast[0] != :false
|
44
|
+
return new
|
45
|
+
end
|
46
|
+
|
47
|
+
# convert to Ruby's false
|
48
|
+
# @return [false] the ruby counter part.
|
49
|
+
def plain_old_ruby_object
|
50
|
+
return false
|
51
|
+
end
|
52
|
+
|
53
|
+
# JSON gem compat
|
54
|
+
# @return [::String] JSONified string representation
|
55
|
+
def to_json
|
56
|
+
return 'false'
|
57
|
+
end
|
58
|
+
|
59
|
+
# Equality. All false instances are equal each other, plus a FalseClass
|
60
|
+
# instance is also equal to this.
|
61
|
+
def == other
|
62
|
+
case other when FalseClass, self.class
|
63
|
+
true
|
64
|
+
else
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Local Variables:
|
72
|
+
# mode: ruby
|
73
|
+
# coding: utf-8-unix
|
74
|
+
# indent-tabs-mode: t
|
75
|
+
# tab-width: 3
|
76
|
+
# ruby-indent-level: 3
|
77
|
+
# fill-column: 79
|
78
|
+
# default-justification: full
|
79
|
+
# End:
|
data/lib/RFC7159/null.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
#! /your/favourite/path/to/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2014 Urabe, Shyouhei. All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# - Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# - Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in
|
14
|
+
# the documentation and/or other materials provided with the
|
15
|
+
# distribution.
|
16
|
+
#
|
17
|
+
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
18
|
+
# names of specific contributors, may be used to endorse or promote
|
19
|
+
# products derived from this software without specific prior written
|
20
|
+
# permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
|
34
|
+
# The null, as defined in RFC7159 section 3.
|
35
|
+
class RFC7159::Null < RFC7159::Value
|
36
|
+
|
37
|
+
# Parse the AST from parser, and convert into corrsponding value.
|
38
|
+
# @param [::Array] ast the AST, generated by the parser
|
39
|
+
# @return [Null] evaluated instance
|
40
|
+
# @raise [ArgumentError] malformed input
|
41
|
+
def self.from_ast ast
|
42
|
+
raise ArgumentError "garbage included: #{ast.inspect}" if ast.length > 1
|
43
|
+
raise ArgumentError "not a false: #{ast.inspect}" if ast[0] != :null
|
44
|
+
return new
|
45
|
+
end
|
46
|
+
|
47
|
+
# convert to Ruby's nil
|
48
|
+
# @return [nil] the ruby counter part.
|
49
|
+
def plain_old_ruby_object
|
50
|
+
return nil
|
51
|
+
end
|
52
|
+
|
53
|
+
# JSON gem compat
|
54
|
+
# @return [::String] JSONified string representation
|
55
|
+
def to_json
|
56
|
+
return 'null'
|
57
|
+
end
|
58
|
+
|
59
|
+
# Equality. All null instances are equal each other, plus a NilClass
|
60
|
+
# instance is also equal to this.
|
61
|
+
def == other
|
62
|
+
case other when NilClass, self.class
|
63
|
+
true
|
64
|
+
else
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Local Variables:
|
72
|
+
# mode: ruby
|
73
|
+
# coding: utf-8-unix
|
74
|
+
# indent-tabs-mode: t
|
75
|
+
# tab-width: 3
|
76
|
+
# ruby-indent-level: 3
|
77
|
+
# fill-column: 79
|
78
|
+
# default-justification: full
|
79
|
+
# End:
|
@@ -0,0 +1,149 @@
|
|
1
|
+
#! /your/favourite/path/to/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2014 Urabe, Shyouhei. All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# - Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# - Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in
|
14
|
+
# the documentation and/or other materials provided with the
|
15
|
+
# distribution.
|
16
|
+
#
|
17
|
+
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
18
|
+
# names of specific contributors, may be used to endorse or promote
|
19
|
+
# products derived from this software without specific prior written
|
20
|
+
# permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
|
34
|
+
require 'bigdecimal'
|
35
|
+
|
36
|
+
# The Numbers, as described in RFC7159 section 6.
|
37
|
+
class RFC7159::Number < RFC7159::Value
|
38
|
+
|
39
|
+
# Notie about technical design: this class _could_ have been made much
|
40
|
+
# faster if we implement the whole type-conversion thing by hand. But that
|
41
|
+
# is very bug-prone. So to avoid unnecessary complexity here we took an
|
42
|
+
# approach to first let everything be BigDecimal, then convert to others
|
43
|
+
# like Float.
|
44
|
+
|
45
|
+
# Parse the AST from parser, and convert into corrsponding values.
|
46
|
+
# @param [::Array] ast the AST, generated by the parser
|
47
|
+
# @return [Number] evaluated instance
|
48
|
+
# @raise [ArgumentError] malformed input
|
49
|
+
def self.from_ast ast
|
50
|
+
type, sign, int, frac, exp = *ast
|
51
|
+
raise ArgumentError, "not an object: #{ast.inspect}" if type != :number
|
52
|
+
raise ArgumentError, "not a number: #{ast.inspect}" if int.nil?
|
53
|
+
new sign, int, frac, exp
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [Numeric] converted numeric
|
57
|
+
# @note this conversion might lose precision. Use `to_d` if you want
|
58
|
+
# something that fully represents this number.
|
59
|
+
def plain_old_ruby_object
|
60
|
+
if /\A[+-]?\d+\z/ =~ @to_s
|
61
|
+
return to_i
|
62
|
+
else
|
63
|
+
return to_f
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [BigDecimal] lossless conversion to numeric
|
68
|
+
def to_d
|
69
|
+
return @to_d
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [::String] the original string
|
73
|
+
def to_s
|
74
|
+
return @to_s.dup # dup just in case.
|
75
|
+
end
|
76
|
+
|
77
|
+
# JSON gem compat
|
78
|
+
# @return [::String] the original string
|
79
|
+
def to_json *;
|
80
|
+
return to_s
|
81
|
+
end
|
82
|
+
|
83
|
+
# @return [Float] conversion to float
|
84
|
+
def to_f
|
85
|
+
# This method must be ideoponent so the result is cached
|
86
|
+
unless @to_f
|
87
|
+
num = to_d.to_f
|
88
|
+
@to_f ||= num # ||= to avoid race
|
89
|
+
end
|
90
|
+
return @to_f
|
91
|
+
end
|
92
|
+
|
93
|
+
# @return [Integer] conversion to integer
|
94
|
+
def to_i
|
95
|
+
# This method must be ideoponent so the result is cached
|
96
|
+
unless @to_i
|
97
|
+
num = to_d.to_i
|
98
|
+
@to_i ||= num # ||= to avoid race
|
99
|
+
end
|
100
|
+
return @to_i
|
101
|
+
end
|
102
|
+
|
103
|
+
# @return [::String] the value in string
|
104
|
+
def inspect
|
105
|
+
sprintf "#<%p:%p>", self.class, plain_old_ruby_object
|
106
|
+
end
|
107
|
+
|
108
|
+
# For pretty print (require 'pp' beforehand)
|
109
|
+
# @param [PP] pp the pp
|
110
|
+
def pretty_print pp
|
111
|
+
pp.object_group self do
|
112
|
+
pp.text ':'
|
113
|
+
plain_old_ruby_object.pretty_print pp
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Number equality is _not_ defined in the RFC so we take liberty of defining
|
118
|
+
# that to be mathematical comparison
|
119
|
+
def == other
|
120
|
+
other == @to_d
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
private_class_method:new
|
126
|
+
# @private
|
127
|
+
def initialize sign, int, frac, exp
|
128
|
+
@sign = sign # nil, '-', or '+'
|
129
|
+
@int = int.join
|
130
|
+
@frac = frac && frac.join # nil, or '.dddd..'
|
131
|
+
@exp = exp && exp.join # nil, or 'e+ddd..'
|
132
|
+
|
133
|
+
# pre-cache common computations
|
134
|
+
@to_s = sprintf "%s%s%s%s", @sign, @int, @frac, @exp
|
135
|
+
@to_s.freeze # just in case
|
136
|
+
@to_d = BigDecimal.new @to_s
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
#
|
141
|
+
# Local Variables:
|
142
|
+
# mode: ruby
|
143
|
+
# coding: utf-8-unix
|
144
|
+
# indent-tabs-mode: t
|
145
|
+
# tab-width: 3
|
146
|
+
# ruby-indent-level: 3
|
147
|
+
# fill-column: 79
|
148
|
+
# default-justification: full
|
149
|
+
# End:
|
@@ -0,0 +1,140 @@
|
|
1
|
+
#! /your/favourite/path/to/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
# Copyright (c) 2014 Urabe, Shyouhei. All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# - Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# - Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in
|
14
|
+
# the documentation and/or other materials provided with the
|
15
|
+
# distribution.
|
16
|
+
#
|
17
|
+
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
18
|
+
# names of specific contributors, may be used to endorse or promote
|
19
|
+
# products derived from this software without specific prior written
|
20
|
+
# permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
|
34
|
+
# The Objects, as described in RFC7159 section 4.
|
35
|
+
class RFC7159::Object < RFC7159::Value
|
36
|
+
|
37
|
+
# Parse the AST from parser, and convert into corrsponding values.
|
38
|
+
# @param [::Array] ast the AST, generated by the parser
|
39
|
+
# @return [Object] evaluated instance
|
40
|
+
# @raise [ArgumentError] malformed input
|
41
|
+
def self.from_ast ast
|
42
|
+
type, *assoc = *ast
|
43
|
+
raise ArgumentError, "not an object: #{ast.inspect}" if type != :object
|
44
|
+
assoc.map! do |a|
|
45
|
+
a.map! do |b|
|
46
|
+
RFC7159::Value.from_ast b
|
47
|
+
end
|
48
|
+
end
|
49
|
+
new assoc
|
50
|
+
end
|
51
|
+
|
52
|
+
# fetch the key.
|
53
|
+
# @note RFC7159 allows identical key to appear multiple times in an object.
|
54
|
+
# @note This is O(1)
|
55
|
+
# @param [::String, String] key key to look at
|
56
|
+
# @return [ [Value] ] corresponding value(s)
|
57
|
+
def [] key
|
58
|
+
ret = @assoc.select do |(k, v)| k == key end
|
59
|
+
ret.map! do |(k, v)| v end
|
60
|
+
return ret
|
61
|
+
end
|
62
|
+
|
63
|
+
# iterates over the pairs.
|
64
|
+
# @yield [key, value] the pair.
|
65
|
+
def each_pair
|
66
|
+
e = Enumerator.new do |y|
|
67
|
+
@assoc.each do |a|
|
68
|
+
y << a
|
69
|
+
end
|
70
|
+
end
|
71
|
+
return block_given? ? e.each(&b) : e
|
72
|
+
end
|
73
|
+
|
74
|
+
alias each each_pair
|
75
|
+
|
76
|
+
# @raise [RuntimeError] keys conflict
|
77
|
+
# @return [::Hash] converted object
|
78
|
+
def plain_old_ruby_object
|
79
|
+
ret = Hash.new
|
80
|
+
@assoc.each do |(k, v)|
|
81
|
+
kk = k.plain_old_ruby_object
|
82
|
+
if ret.include? kk
|
83
|
+
raise RuntimeError, "key #{kk} conflict."
|
84
|
+
else
|
85
|
+
vv = v.plain_old_ruby_object
|
86
|
+
ret.store kk, vv
|
87
|
+
end
|
88
|
+
end
|
89
|
+
return ret
|
90
|
+
end
|
91
|
+
|
92
|
+
alias to_h plain_old_ruby_object
|
93
|
+
alias to_hash plain_old_ruby_object
|
94
|
+
|
95
|
+
# @return [::String] the object in string
|
96
|
+
def inspect
|
97
|
+
hdr = sprintf "#<%p:%#016x {", self.class, self.object_id << 1
|
98
|
+
map = @assoc.map do |(k, v)|
|
99
|
+
sprintf '%p: %p', k.to_s, v
|
100
|
+
end.join ', '
|
101
|
+
hdr << map << '}>'
|
102
|
+
end
|
103
|
+
|
104
|
+
# For pretty print
|
105
|
+
# @param [PP] pp the pp
|
106
|
+
def pretty_print pp
|
107
|
+
hdr = sprintf '#<%p:%#016x', self.class, self.object_id << 1
|
108
|
+
pp.group 1, hdr, '>' do
|
109
|
+
pp.breakable
|
110
|
+
pp.group 1, '{', '}' do
|
111
|
+
@assoc.each_with_index do |(k, v), i|
|
112
|
+
pp.breakable ',' if i.nonzero?
|
113
|
+
k.to_s.pretty_print pp
|
114
|
+
pp.text ': '
|
115
|
+
v.pretty_print pp
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
private_class_method:new
|
123
|
+
# @private
|
124
|
+
def initialize assoc
|
125
|
+
@assoc = assoc
|
126
|
+
@assoc.each {|i| i.freeze }
|
127
|
+
@assoc.freeze
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# Local Variables:
|
133
|
+
# mode: ruby
|
134
|
+
# coding: utf-8-unix
|
135
|
+
# indent-tabs-mode: t
|
136
|
+
# tab-width: 3
|
137
|
+
# ruby-indent-level: 3
|
138
|
+
# fill-column: 79
|
139
|
+
# default-justification: full
|
140
|
+
# End:
|