xnlogic-transit-ruby 0.8.572-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yard_redcarpet_ext +1 -0
- data/.yardopts +6 -0
- data/CHANGELOG.md +31 -0
- data/Jarfile +10 -0
- data/LICENSE +202 -0
- data/README.md +172 -0
- data/lib/transit.jar +0 -0
- data/lib/transit.rb +108 -0
- data/lib/transit/date_time_util.rb +39 -0
- data/lib/transit/decoder.rb +123 -0
- data/lib/transit/marshaler/base.rb +193 -0
- data/lib/transit/marshaler/jruby/json.rb +38 -0
- data/lib/transit/marshaler/jruby/messagepack.rb +25 -0
- data/lib/transit/read_handlers.rb +113 -0
- data/lib/transit/reader.rb +65 -0
- data/lib/transit/rolling_cache.rb +70 -0
- data/lib/transit/transit_types.rb +258 -0
- data/lib/transit/write_handlers.rb +438 -0
- data/lib/transit/writer.rb +68 -0
- data/spec/spec_helper.rb +85 -0
- data/spec/transit/date_time_util_spec.rb +65 -0
- data/spec/transit/decoder_spec.rb +60 -0
- data/spec/transit/exemplar_spec.rb +150 -0
- data/spec/transit/marshaler_spec.rb +30 -0
- data/spec/transit/reader_spec.rb +170 -0
- data/spec/transit/rolling_cache_spec.rb +94 -0
- data/spec/transit/round_trip_spec.rb +172 -0
- data/spec/transit/transit_types_spec.rb +144 -0
- data/spec/transit/writer_spec.rb +319 -0
- metadata +171 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
# Copyright 2014 Cognitect. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS-IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Transit
|
16
|
+
# @api private
|
17
|
+
module DateTimeUtil
|
18
|
+
def to_millis(v)
|
19
|
+
case v
|
20
|
+
when DateTime
|
21
|
+
t = v.new_offset(0).to_time
|
22
|
+
when Date
|
23
|
+
t = Time.gm(v.year, v.month, v.day)
|
24
|
+
when Time
|
25
|
+
t = v
|
26
|
+
else
|
27
|
+
raise "Don't know how to get millis from #{t.inspect}"
|
28
|
+
end
|
29
|
+
(t.to_i * 1000) + (t.usec / 1000.0).round
|
30
|
+
end
|
31
|
+
|
32
|
+
def from_millis(millis)
|
33
|
+
t = Time.at(millis / 1000).utc
|
34
|
+
DateTime.new(t.year, t.month, t.day, t.hour, t.min, t.sec + (millis % 1000 * 0.001))
|
35
|
+
end
|
36
|
+
|
37
|
+
module_function :to_millis, :from_millis
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# Copyright 2014 Cognitect. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS-IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Transit
|
16
|
+
# Converts a transit value to an instance of a type
|
17
|
+
# @api private
|
18
|
+
class Decoder
|
19
|
+
MUTEX = Mutex.new
|
20
|
+
HANDLER_CACHE = {}
|
21
|
+
|
22
|
+
ESC_ESC = "#{ESC}#{ESC}"
|
23
|
+
ESC_SUB = "#{ESC}#{SUB}"
|
24
|
+
ESC_RES = "#{ESC}#{RES}"
|
25
|
+
|
26
|
+
IDENTITY = ->(v){v}
|
27
|
+
|
28
|
+
GROUND_TAGS = %w[_ s ? i d b ' array map]
|
29
|
+
|
30
|
+
def initialize(options={})
|
31
|
+
custom_handlers = options[:handlers] || {}
|
32
|
+
custom_handlers.each {|k,v| validate_handler(k,v)}
|
33
|
+
MUTEX.synchronize do
|
34
|
+
if HANDLER_CACHE.has_key?(custom_handlers)
|
35
|
+
@handlers = HANDLER_CACHE[custom_handlers]
|
36
|
+
else
|
37
|
+
@handlers = ReadHandlers::DEFAULT_READ_HANDLERS.merge(custom_handlers)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
@default_handler = options[:default_handler] || ReadHandlers::DEFAULT_READ_HANDLER
|
42
|
+
end
|
43
|
+
|
44
|
+
# @api private
|
45
|
+
class Tag < String; end
|
46
|
+
|
47
|
+
# Decodes a transit value to a corresponding object
|
48
|
+
#
|
49
|
+
# @param node a transit value to be decoded
|
50
|
+
# @param cache
|
51
|
+
# @param as_map_key
|
52
|
+
# @return decoded object
|
53
|
+
def decode(node, cache=RollingCache.new, as_map_key=false)
|
54
|
+
case node
|
55
|
+
when String
|
56
|
+
if cache.has_key?(node)
|
57
|
+
cache.read(node)
|
58
|
+
else
|
59
|
+
parsed = if !node.start_with?(ESC)
|
60
|
+
node
|
61
|
+
elsif node.start_with?(TAG)
|
62
|
+
Tag.new(node[2..-1])
|
63
|
+
elsif handler = @handlers[node[1]]
|
64
|
+
handler.from_rep(node[2..-1])
|
65
|
+
elsif node.start_with?(ESC_ESC, ESC_SUB, ESC_RES)
|
66
|
+
node[1..-1]
|
67
|
+
else
|
68
|
+
@default_handler.from_rep(node[1], node[2..-1])
|
69
|
+
end
|
70
|
+
if cache.cacheable?(node, as_map_key)
|
71
|
+
cache.write(parsed)
|
72
|
+
end
|
73
|
+
parsed
|
74
|
+
end
|
75
|
+
when Array
|
76
|
+
return node if node.empty?
|
77
|
+
e0 = decode(node.shift, cache, false)
|
78
|
+
if e0 == MAP_AS_ARRAY
|
79
|
+
decode(Hash[*node], cache)
|
80
|
+
elsif Tag === e0
|
81
|
+
v = decode(node.shift, cache)
|
82
|
+
if handler = @handlers[e0]
|
83
|
+
handler.from_rep(v)
|
84
|
+
else
|
85
|
+
@default_handler.from_rep(e0,v)
|
86
|
+
end
|
87
|
+
else
|
88
|
+
[e0] + node.map {|e| decode(e, cache, as_map_key)}
|
89
|
+
end
|
90
|
+
when Hash
|
91
|
+
if node.size == 1
|
92
|
+
k = decode(node.keys.first, cache, true)
|
93
|
+
v = decode(node.values.first, cache, false)
|
94
|
+
if Tag === k
|
95
|
+
if handler = @handlers[k]
|
96
|
+
handler.from_rep(v)
|
97
|
+
else
|
98
|
+
@default_handler.from_rep(k,v)
|
99
|
+
end
|
100
|
+
else
|
101
|
+
{k => v}
|
102
|
+
end
|
103
|
+
else
|
104
|
+
node.keys.each do |k|
|
105
|
+
node.store(decode(k, cache, true), decode(node.delete(k), cache))
|
106
|
+
end
|
107
|
+
node
|
108
|
+
end
|
109
|
+
else
|
110
|
+
node
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def validate_handler(key, handler)
|
115
|
+
raise ArgumentError.new(CAN_NOT_OVERRIDE_GROUND_TYPES_MESSAGE) if GROUND_TAGS.include?(key)
|
116
|
+
end
|
117
|
+
|
118
|
+
CAN_NOT_OVERRIDE_GROUND_TYPES_MESSAGE = <<-MSG
|
119
|
+
You can not supply custom read handlers for ground types.
|
120
|
+
MSG
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
# Copyright 2014 Cognitect. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS-IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Transit
|
16
|
+
# Transit::Writer marshals Ruby objects as transit values to an output stream.
|
17
|
+
# @see https://github.com/cognitect/transit-format
|
18
|
+
module Marshaler
|
19
|
+
|
20
|
+
HANDLER_CACHE = {}
|
21
|
+
VERBOSE_HANDLER_CACHE = {}
|
22
|
+
MUTEX = Mutex.new
|
23
|
+
|
24
|
+
# @api private
|
25
|
+
# Included in VerboseJson subclasses. Defined here to make it
|
26
|
+
# available in CRuby and JRuby environments.
|
27
|
+
module VerboseHandlers
|
28
|
+
def build_handlers(custom_handlers)
|
29
|
+
if VERBOSE_HANDLER_CACHE.has_key?(custom_handlers)
|
30
|
+
VERBOSE_HANDLER_CACHE[custom_handlers]
|
31
|
+
else
|
32
|
+
handlers = super(custom_handlers).reduce({}) do |h, (k,v)|
|
33
|
+
if v.respond_to?(:verbose_handler) && vh = v.verbose_handler
|
34
|
+
h.store(k, vh)
|
35
|
+
else
|
36
|
+
h.store(k, v)
|
37
|
+
end
|
38
|
+
h
|
39
|
+
end
|
40
|
+
VERBOSE_HANDLER_CACHE[custom_handlers] = handlers
|
41
|
+
handlers
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
module Base
|
48
|
+
def parse_options(opts)
|
49
|
+
MUTEX.synchronize do
|
50
|
+
@handlers = build_handlers(opts[:handlers])
|
51
|
+
end
|
52
|
+
@handlers.values.each { |h| h.handlers=(@handlers) if h.respond_to?(:handlers=) }
|
53
|
+
end
|
54
|
+
|
55
|
+
def build_handlers(custom_handlers)
|
56
|
+
if HANDLER_CACHE.has_key?(custom_handlers)
|
57
|
+
HANDLER_CACHE[custom_handlers]
|
58
|
+
else
|
59
|
+
handlers = WriteHandlers::DEFAULT_WRITE_HANDLERS.dup
|
60
|
+
handlers.merge!(custom_handlers) if custom_handlers
|
61
|
+
HANDLER_CACHE[custom_handlers] = handlers
|
62
|
+
handlers
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def find_handler(obj)
|
67
|
+
obj.class.ancestors.each do |a|
|
68
|
+
if handler = @handlers[a]
|
69
|
+
return handler
|
70
|
+
end
|
71
|
+
end
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
def escape(s)
|
76
|
+
if s.start_with?(SUB,ESC,RES) && s != "#{SUB} "
|
77
|
+
"#{ESC}#{s}"
|
78
|
+
else
|
79
|
+
s
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def emit_nil(as_map_key, cache)
|
84
|
+
as_map_key ? emit_string(ESC, "_", nil, true, cache) : emit_value(nil)
|
85
|
+
end
|
86
|
+
|
87
|
+
def emit_string(prefix, tag, value, as_map_key, cache)
|
88
|
+
encoded = "#{prefix}#{tag}#{value}"
|
89
|
+
if cache.cacheable?(encoded, as_map_key)
|
90
|
+
emit_value(cache.write(encoded), as_map_key)
|
91
|
+
else
|
92
|
+
emit_value(encoded, as_map_key)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def emit_boolean(handler, b, as_map_key, cache)
|
97
|
+
as_map_key ? emit_string(ESC, "?", handler.string_rep(b), true, cache) : emit_value(b)
|
98
|
+
end
|
99
|
+
|
100
|
+
def emit_double(d, as_map_key, cache)
|
101
|
+
as_map_key ? emit_string(ESC, "d", d, true, cache) : emit_value(d)
|
102
|
+
end
|
103
|
+
|
104
|
+
def emit_array(a, cache)
|
105
|
+
emit_array_start(a.size)
|
106
|
+
a.each {|e| marshal(e, false, cache)}
|
107
|
+
emit_array_end
|
108
|
+
end
|
109
|
+
|
110
|
+
def emit_map(m, cache)
|
111
|
+
emit_map_start(m.size)
|
112
|
+
m.each do |k,v|
|
113
|
+
marshal(k, true, cache)
|
114
|
+
marshal(v, false, cache)
|
115
|
+
end
|
116
|
+
emit_map_end
|
117
|
+
end
|
118
|
+
|
119
|
+
def emit_tagged_value(tag, rep, cache)
|
120
|
+
emit_array_start(2)
|
121
|
+
emit_string(ESC, "#", tag, false, cache)
|
122
|
+
marshal(rep, false, cache)
|
123
|
+
emit_array_end
|
124
|
+
end
|
125
|
+
|
126
|
+
def emit_encoded(handler, tag, obj, as_map_key, cache)
|
127
|
+
if tag.length == 1
|
128
|
+
rep = handler.rep(obj)
|
129
|
+
if String === rep
|
130
|
+
emit_string(ESC, tag, rep, as_map_key, cache)
|
131
|
+
elsif as_map_key || @prefer_strings
|
132
|
+
if str_rep = handler.string_rep(obj)
|
133
|
+
emit_string(ESC, tag, str_rep, as_map_key, cache)
|
134
|
+
else
|
135
|
+
raise "Cannot be encoded as String: " + {:tag => tag, :rep => rep, :obj => obj}.to_s
|
136
|
+
end
|
137
|
+
else
|
138
|
+
emit_tagged_value(tag, handler.rep(obj), cache)
|
139
|
+
end
|
140
|
+
elsif as_map_key
|
141
|
+
raise "Cannot be used as a map key: " + {:tag => tag, :rep => rep, :obj => obj}.to_s
|
142
|
+
else
|
143
|
+
emit_tagged_value(tag, handler.rep(obj), cache)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def marshal(obj, as_map_key, cache)
|
148
|
+
if handler = find_handler(obj)
|
149
|
+
tag = handler.tag(obj)
|
150
|
+
case tag
|
151
|
+
when "_"
|
152
|
+
emit_nil(as_map_key, cache)
|
153
|
+
when "?"
|
154
|
+
emit_boolean(handler, obj, as_map_key, cache)
|
155
|
+
when "s"
|
156
|
+
emit_string(nil, nil, escape(handler.rep(obj)), as_map_key, cache)
|
157
|
+
when "i"
|
158
|
+
emit_int(tag, handler.rep(obj), as_map_key, cache)
|
159
|
+
when "d"
|
160
|
+
emit_double(handler.rep(obj), as_map_key, cache)
|
161
|
+
when "'"
|
162
|
+
emit_tagged_value(tag, handler.rep(obj), cache)
|
163
|
+
when "array"
|
164
|
+
emit_array(handler.rep(obj), cache)
|
165
|
+
when "map"
|
166
|
+
emit_map(handler.rep(obj), cache)
|
167
|
+
else
|
168
|
+
emit_encoded(handler, tag, obj, as_map_key, cache)
|
169
|
+
end
|
170
|
+
else
|
171
|
+
raise "Can not find a Write Handler for #{obj.inspect}."
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def marshal_top(obj, cache=RollingCache.new)
|
176
|
+
if handler = find_handler(obj)
|
177
|
+
if tag = handler.tag(obj)
|
178
|
+
if tag.length == 1
|
179
|
+
marshal(TaggedValue.new(QUOTE, obj), false, cache)
|
180
|
+
else
|
181
|
+
marshal(obj, false, cache)
|
182
|
+
end
|
183
|
+
flush
|
184
|
+
else
|
185
|
+
raise "Handler must provide a non-nil tag: #{handler.inspect}"
|
186
|
+
end
|
187
|
+
else
|
188
|
+
raise "Can not find a Write Handler for #{obj.inspect}."
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright 2014 Cognitect. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS-IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Transit
|
16
|
+
module Marshaler
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
module JsonBase
|
20
|
+
def initialize(io, opts)
|
21
|
+
parse_options(opts)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @api private
|
26
|
+
class Json
|
27
|
+
include Transit::Marshaler::Base
|
28
|
+
include Transit::Marshaler::JsonBase
|
29
|
+
end
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
class VerboseJson
|
33
|
+
include Transit::Marshaler::Base
|
34
|
+
include Transit::Marshaler::JsonBase
|
35
|
+
include Transit::Marshaler::VerboseHandlers
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright 2014 Cognitect. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS-IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Transit
|
16
|
+
module Marshaler
|
17
|
+
class MessagePack
|
18
|
+
include Transit::Marshaler::Base
|
19
|
+
|
20
|
+
def initialize(io, opts)
|
21
|
+
parse_options(opts)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# Copyright 2014 Cognitect. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS-IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
module Transit
|
16
|
+
# @see Transit::WriteHandlers
|
17
|
+
module ReadHandlers
|
18
|
+
class Default
|
19
|
+
def from_rep(tag,val) TaggedValue.new(tag, val) end
|
20
|
+
end
|
21
|
+
class NilHandler
|
22
|
+
def from_rep(_) nil end
|
23
|
+
end
|
24
|
+
class KeywordHandler
|
25
|
+
def from_rep(v) v.to_sym end
|
26
|
+
end
|
27
|
+
class BooleanHandler
|
28
|
+
def from_rep(v) v == "t" end
|
29
|
+
end
|
30
|
+
class ByteArrayHandler
|
31
|
+
def from_rep(v) ByteArray.from_base64(v) end
|
32
|
+
end
|
33
|
+
class FloatHandler
|
34
|
+
def from_rep(v) Float(v) end
|
35
|
+
end
|
36
|
+
class IntegerHandler
|
37
|
+
def from_rep(v) v.to_i end
|
38
|
+
end
|
39
|
+
class BigIntegerHandler
|
40
|
+
def from_rep(v) v.to_i end
|
41
|
+
end
|
42
|
+
class BigDecimalHandler
|
43
|
+
def from_rep(v) BigDecimal.new(v) end
|
44
|
+
end
|
45
|
+
class SpecialNumbersHandler
|
46
|
+
def from_rep(v)
|
47
|
+
case v
|
48
|
+
when "NaN" then Float::NAN
|
49
|
+
when "INF" then Float::INFINITY
|
50
|
+
when "-INF" then -Float::INFINITY
|
51
|
+
else raise ArgumentError.new("Don't know how to handle #{v.inspect} for the \"z\" tag")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
class IdentityHandler
|
56
|
+
def from_rep(v) v end
|
57
|
+
end
|
58
|
+
class SymbolHandler
|
59
|
+
def from_rep(v) Transit::Symbol.new(v) end
|
60
|
+
end
|
61
|
+
class TimeStringHandler
|
62
|
+
def from_rep(v) DateTime.iso8601(v) end
|
63
|
+
end
|
64
|
+
class TimeIntHandler
|
65
|
+
def from_rep(v) DateTimeUtil.from_millis(v.to_i) end
|
66
|
+
end
|
67
|
+
class UuidHandler
|
68
|
+
def from_rep(v) UUID.new(v) end
|
69
|
+
end
|
70
|
+
class UriHandler
|
71
|
+
def from_rep(v) Addressable::URI.parse(v) end
|
72
|
+
end
|
73
|
+
class SetHandler
|
74
|
+
def from_rep(v) Set.new(v) end
|
75
|
+
end
|
76
|
+
class LinkHandler
|
77
|
+
def from_rep(v) Link.new(v) end
|
78
|
+
end
|
79
|
+
class CmapHandler
|
80
|
+
def from_rep(v) Hash[*v] end
|
81
|
+
end
|
82
|
+
class RatioHandler
|
83
|
+
def from_rep(v) Rational(v[0], v[1]) end
|
84
|
+
end
|
85
|
+
|
86
|
+
DEFAULT_READ_HANDLERS = {
|
87
|
+
"_" => NilHandler.new,
|
88
|
+
":" => KeywordHandler.new,
|
89
|
+
"?" => BooleanHandler.new,
|
90
|
+
"b" => ByteArrayHandler.new,
|
91
|
+
"d" => FloatHandler.new,
|
92
|
+
"i" => IntegerHandler.new,
|
93
|
+
"n" => BigIntegerHandler.new,
|
94
|
+
"f" => BigDecimalHandler.new,
|
95
|
+
"c" => IdentityHandler.new,
|
96
|
+
"$" => SymbolHandler.new,
|
97
|
+
"t" => TimeStringHandler.new,
|
98
|
+
"m" => TimeIntHandler.new,
|
99
|
+
"u" => UuidHandler.new,
|
100
|
+
"r" => UriHandler.new,
|
101
|
+
"'" => IdentityHandler.new,
|
102
|
+
"z" => SpecialNumbersHandler.new,
|
103
|
+
"set" => SetHandler.new,
|
104
|
+
"link" => LinkHandler.new,
|
105
|
+
"list" => IdentityHandler.new,
|
106
|
+
"cmap" => CmapHandler.new,
|
107
|
+
"ratio" => RatioHandler.new
|
108
|
+
}.freeze
|
109
|
+
|
110
|
+
DEFAULT_READ_HANDLER = Default.new
|
111
|
+
|
112
|
+
end
|
113
|
+
end
|