restify 2.0.1 → 2.1.0
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/CHANGELOG.md +16 -0
- data/README.md +1 -1
- data/lib/restify/adapter/base.rb +1 -1
- data/lib/restify/cache.rb +1 -1
- data/lib/restify/relation.rb +7 -11
- data/lib/restify/response.rb +2 -2
- data/lib/restify/version.rb +2 -2
- data/spec/restify/adapter/base_spec.rb +33 -0
- data/spec/restify/context_spec.rb +2 -2
- data/spec/restify/features/opentelemetry_spec.rb +1 -1
- data/spec/restify/global_spec.rb +50 -1
- data/spec/restify/link_spec.rb +13 -3
- data/spec/restify/relation_spec.rb +79 -7
- data/spec/restify/resource_spec.rb +6 -0
- data/spec/restify_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -1
- data/vendor/bundle/ruby/4.0.0/bundler/gems/my-rubocop-2b861962124a/LICENSE +21 -0
- data/vendor/bundle/ruby/4.0.0/bundler/gems/my-rubocop-2b861962124a/README.md +23 -0
- data/vendor/bundle/ruby/4.0.0/gems/activesupport-8.1.3/CHANGELOG.md +561 -0
- data/vendor/bundle/ruby/4.0.0/gems/activesupport-8.1.3/MIT-LICENSE +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/activesupport-8.1.3/README.rdoc +40 -0
- data/vendor/bundle/ruby/4.0.0/gems/addressable-2.9.0/CHANGELOG.md +326 -0
- data/vendor/bundle/ruby/4.0.0/gems/addressable-2.9.0/LICENSE.txt +202 -0
- data/vendor/bundle/ruby/4.0.0/gems/addressable-2.9.0/README.md +121 -0
- data/vendor/bundle/ruby/4.0.0/gems/ast-2.4.3/LICENSE.MIT +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/ast-2.4.3/README.YARD.md +12 -0
- data/vendor/bundle/ruby/4.0.0/gems/base64-0.3.0/README.md +48 -0
- data/vendor/bundle/ruby/4.0.0/gems/bigdecimal-4.1.2/LICENSE +56 -0
- data/vendor/bundle/ruby/4.0.0/gems/concurrent-ruby-1.3.7/CHANGELOG.md +615 -0
- data/vendor/bundle/ruby/4.0.0/gems/concurrent-ruby-1.3.7/LICENSE.txt +21 -0
- data/vendor/bundle/ruby/4.0.0/gems/concurrent-ruby-1.3.7/README.md +409 -0
- data/vendor/bundle/ruby/4.0.0/gems/connection_pool-3.0.2/LICENSE +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/connection_pool-3.0.2/README.md +182 -0
- data/vendor/bundle/ruby/4.0.0/gems/crack-1.0.1/LICENSE +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/crack-1.0.1/README.md +43 -0
- data/vendor/bundle/ruby/4.0.0/gems/diff-lcs-1.6.2/CHANGELOG.md +518 -0
- data/vendor/bundle/ruby/4.0.0/gems/diff-lcs-1.6.2/README.md +92 -0
- data/vendor/bundle/ruby/4.0.0/gems/docile-1.4.1/LICENSE +21 -0
- data/vendor/bundle/ruby/4.0.0/gems/docile-1.4.1/README.md +409 -0
- data/vendor/bundle/ruby/4.0.0/gems/drb-2.2.3/LICENSE.txt +22 -0
- data/vendor/bundle/ruby/4.0.0/gems/ethon-0.18.0/CHANGELOG.md +417 -0
- data/vendor/bundle/ruby/4.0.0/gems/ethon-0.18.0/LICENSE +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/ethon-0.18.0/README.md +118 -0
- data/vendor/bundle/ruby/4.0.0/gems/ffi-1.17.4-x86_64-linux-gnu/CHANGELOG.md +507 -0
- data/vendor/bundle/ruby/4.0.0/gems/ffi-1.17.4-x86_64-linux-gnu/LICENSE +24 -0
- data/vendor/bundle/ruby/4.0.0/gems/ffi-1.17.4-x86_64-linux-gnu/LICENSE.SPECS +22 -0
- data/vendor/bundle/ruby/4.0.0/gems/ffi-1.17.4-x86_64-linux-gnu/README.md +138 -0
- data/vendor/bundle/ruby/4.0.0/gems/hashdiff-1.2.1/LICENSE +19 -0
- data/vendor/bundle/ruby/4.0.0/gems/hashdiff-1.2.1/README.md +323 -0
- data/vendor/bundle/ruby/4.0.0/gems/hashdiff-1.2.1/changelog.md +127 -0
- data/vendor/bundle/ruby/4.0.0/gems/hitimes-3.2.0/LICENSE.txt +16 -0
- data/vendor/bundle/ruby/4.0.0/gems/hitimes-3.2.0/README.md +187 -0
- data/vendor/bundle/ruby/4.0.0/gems/i18n-1.15.2/MIT-LICENSE +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/i18n-1.15.2/README.md +139 -0
- data/vendor/bundle/ruby/4.0.0/gems/json-2.19.9/README.md +310 -0
- data/vendor/bundle/ruby/4.0.0/gems/language_server-protocol-3.17.0.5/LICENSE.txt +21 -0
- data/vendor/bundle/ruby/4.0.0/gems/language_server-protocol-3.17.0.5/README.md +88 -0
- data/vendor/bundle/ruby/4.0.0/gems/lint_roller-1.1.0/CHANGELOG.md +15 -0
- data/vendor/bundle/ruby/4.0.0/gems/lint_roller-1.1.0/LICENSE.txt +21 -0
- data/vendor/bundle/ruby/4.0.0/gems/lint_roller-1.1.0/README.md +173 -0
- data/vendor/bundle/ruby/4.0.0/gems/little-plugger-1.1.4/README.rdoc +53 -0
- data/vendor/bundle/ruby/4.0.0/gems/logger-1.7.0/README.md +104 -0
- data/vendor/bundle/ruby/4.0.0/gems/logging-2.4.0/LICENSE +22 -0
- data/vendor/bundle/ruby/4.0.0/gems/logging-2.4.0/README.md +140 -0
- data/vendor/bundle/ruby/4.0.0/gems/minitest-6.0.6/README.rdoc +763 -0
- data/vendor/bundle/ruby/4.0.0/gems/msgpack-1.8.3/ChangeLog +383 -0
- data/vendor/bundle/ruby/4.0.0/gems/msgpack-1.8.3/LICENSE +177 -0
- data/vendor/bundle/ruby/4.0.0/gems/msgpack-1.8.3/README.md +302 -0
- data/vendor/bundle/ruby/4.0.0/gems/multi_json-1.21.1/LICENSE.md +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/multi_json-1.21.1/README.md +281 -0
- data/vendor/bundle/ruby/4.0.0/gems/nio4r-2.7.5/ext/libev/LICENSE +37 -0
- data/vendor/bundle/ruby/4.0.0/gems/nio4r-2.7.5/ext/libev/README +59 -0
- data/vendor/bundle/ruby/4.0.0/gems/nio4r-2.7.5/license.md +80 -0
- data/vendor/bundle/ruby/4.0.0/gems/nio4r-2.7.5/readme.md +91 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-api-1.10.0/CHANGELOG.md +219 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-api-1.10.0/LICENSE +201 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-api-1.10.0/README.md +68 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-common-0.25.0/CHANGELOG.md +110 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-common-0.25.0/LICENSE +201 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-common-0.25.0/README.md +62 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-instrumentation-base-0.26.1/CHANGELOG.md +97 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-instrumentation-base-0.26.1/LICENSE +201 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-instrumentation-base-0.26.1/README.md +155 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-instrumentation-ethon-0.29.0/CHANGELOG.md +192 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-instrumentation-ethon-0.29.0/LICENSE +201 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-instrumentation-ethon-0.29.0/README.md +66 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-registry-0.6.0/CHANGELOG.md +31 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-registry-0.6.0/LICENSE +201 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-registry-0.6.0/README.md +40 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-sdk-1.12.0/CHANGELOG.md +302 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-sdk-1.12.0/LICENSE +201 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-sdk-1.12.0/README.md +101 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-semantic_conventions-1.41.0/CHANGELOG.md +65 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-semantic_conventions-1.41.0/LICENSE +201 -0
- data/vendor/bundle/ruby/4.0.0/gems/opentelemetry-semantic_conventions-1.41.0/README.md +115 -0
- data/vendor/bundle/ruby/4.0.0/gems/parallel-2.1.0/MIT-LICENSE.txt +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/parser-3.3.11.1/LICENSE.txt +26 -0
- data/vendor/bundle/ruby/4.0.0/gems/prism-1.9.0/CHANGELOG.md +786 -0
- data/vendor/bundle/ruby/4.0.0/gems/prism-1.9.0/LICENSE.md +7 -0
- data/vendor/bundle/ruby/4.0.0/gems/prism-1.9.0/README.md +143 -0
- data/vendor/bundle/ruby/4.0.0/gems/public_suffix-7.0.5/CHANGELOG.md +649 -0
- data/vendor/bundle/ruby/4.0.0/gems/public_suffix-7.0.5/LICENSE.txt +22 -0
- data/vendor/bundle/ruby/4.0.0/gems/public_suffix-7.0.5/README.md +231 -0
- data/vendor/bundle/ruby/4.0.0/gems/puma-8.0.2/LICENSE +29 -0
- data/vendor/bundle/ruby/4.0.0/gems/puma-8.0.2/README.md +484 -0
- data/vendor/bundle/ruby/4.0.0/gems/puma-8.0.2/docs/jungle/README.md +9 -0
- data/vendor/bundle/ruby/4.0.0/gems/puma-8.0.2/docs/jungle/rc.d/README.md +74 -0
- data/vendor/bundle/ruby/4.0.0/gems/racc-1.8.1/ChangeLog +846 -0
- data/vendor/bundle/ruby/4.0.0/gems/racc-1.8.1/README.ja.rdoc +58 -0
- data/vendor/bundle/ruby/4.0.0/gems/racc-1.8.1/README.rdoc +60 -0
- data/vendor/bundle/ruby/4.0.0/gems/rack-3.2.6/CHANGELOG.md +1346 -0
- data/vendor/bundle/ruby/4.0.0/gems/rack-3.2.6/MIT-LICENSE +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/rack-3.2.6/README.md +384 -0
- data/vendor/bundle/ruby/4.0.0/gems/rainbow-3.1.1/Changelog.md +101 -0
- data/vendor/bundle/ruby/4.0.0/gems/rainbow-3.1.1/LICENSE +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/rainbow-3.1.1/README.markdown +227 -0
- data/vendor/bundle/ruby/4.0.0/gems/rake-13.4.2/MIT-LICENSE +21 -0
- data/vendor/bundle/ruby/4.0.0/gems/rake-13.4.2/README.rdoc +155 -0
- data/vendor/bundle/ruby/4.0.0/gems/rake-release-1.4.0/LICENSE +21 -0
- data/vendor/bundle/ruby/4.0.0/gems/rake-release-1.4.0/README.md +107 -0
- data/vendor/bundle/ruby/4.0.0/gems/regexp_parser-2.12.0/LICENSE +22 -0
- data/vendor/bundle/ruby/4.0.0/gems/rexml-3.4.4/LICENSE.txt +22 -0
- data/vendor/bundle/ruby/4.0.0/gems/rexml-3.4.4/README.md +57 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-3.13.2/LICENSE.md +27 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-3.13.2/README.md +47 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-core-3.13.6/Changelog.md +2447 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-core-3.13.6/LICENSE.md +26 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-core-3.13.6/README.md +389 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-expectations-3.13.5/Changelog.md +1366 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-expectations-3.13.5/LICENSE.md +25 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-expectations-3.13.5/README.md +326 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-mocks-3.13.8/Changelog.md +1351 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-mocks-3.13.8/LICENSE.md +25 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-mocks-3.13.8/README.md +465 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-support-3.13.7/Changelog.md +444 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-support-3.13.7/LICENSE.md +23 -0
- data/vendor/bundle/ruby/4.0.0/gems/rspec-support-3.13.7/README.md +40 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-1.88.0/LICENSE.txt +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-1.88.0/README.md +255 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-ast-1.49.1/LICENSE.txt +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-ast-1.49.1/README.md +54 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-capybara-2.23.0/CHANGELOG.md +116 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-capybara-2.23.0/MIT-LICENSE.md +21 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-capybara-2.23.0/README.md +91 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-factory_bot-2.28.0/CHANGELOG.md +135 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-factory_bot-2.28.0/MIT-LICENSE.md +21 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-factory_bot-2.28.0/README.md +91 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-performance-1.26.1/LICENSE.txt +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-performance-1.26.1/README.md +100 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-rspec-3.10.2/CHANGELOG.md +1136 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-rspec-3.10.2/MIT-LICENSE.md +21 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-rspec-3.10.2/README.md +112 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-rspec_rails-2.32.0/CHANGELOG.md +98 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-rspec_rails-2.32.0/MIT-LICENSE.md +21 -0
- data/vendor/bundle/ruby/4.0.0/gems/rubocop-rspec_rails-2.32.0/README.md +93 -0
- data/vendor/bundle/ruby/4.0.0/gems/ruby-progressbar-1.13.0/LICENSE.txt +19 -0
- data/vendor/bundle/ruby/4.0.0/gems/ruby-progressbar-1.13.0/README.md +131 -0
- data/vendor/bundle/ruby/4.0.0/gems/securerandom-0.4.1/README.md +72 -0
- data/vendor/bundle/ruby/4.0.0/gems/simplecov-0.22.0/CHANGELOG.md +191 -0
- data/vendor/bundle/ruby/4.0.0/gems/simplecov-0.22.0/LICENSE +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/simplecov-0.22.0/README.md +974 -0
- data/vendor/bundle/ruby/4.0.0/gems/simplecov-cobertura-3.2.0/LICENSE +202 -0
- data/vendor/bundle/ruby/4.0.0/gems/simplecov-cobertura-3.2.0/README.md +65 -0
- data/vendor/bundle/ruby/4.0.0/gems/simplecov-html-0.13.2/CHANGELOG.md +114 -0
- data/vendor/bundle/ruby/4.0.0/gems/simplecov-html-0.13.2/LICENSE +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/simplecov-html-0.13.2/README.md +30 -0
- data/vendor/bundle/ruby/4.0.0/gems/simplecov_json_formatter-0.1.4/CHANGELOG.md +13 -0
- data/vendor/bundle/ruby/4.0.0/gems/simplecov_json_formatter-0.1.4/README.md +29 -0
- data/vendor/bundle/ruby/4.0.0/gems/typhoeus-1.6.0/CHANGELOG.md +465 -0
- data/vendor/bundle/ruby/4.0.0/gems/typhoeus-1.6.0/LICENSE +22 -0
- data/vendor/bundle/ruby/4.0.0/gems/typhoeus-1.6.0/README.md +588 -0
- data/vendor/bundle/ruby/4.0.0/gems/tzinfo-2.0.6/LICENSE +19 -0
- data/vendor/bundle/ruby/4.0.0/gems/tzinfo-2.0.6/README.md +406 -0
- data/vendor/bundle/ruby/4.0.0/gems/unicode-display_width-3.2.0/CHANGELOG.md +299 -0
- data/vendor/bundle/ruby/4.0.0/gems/unicode-display_width-3.2.0/MIT-LICENSE.txt +22 -0
- data/vendor/bundle/ruby/4.0.0/gems/unicode-display_width-3.2.0/README.md +194 -0
- data/vendor/bundle/ruby/4.0.0/gems/unicode-emoji-4.2.0/CHANGELOG.md +202 -0
- data/vendor/bundle/ruby/4.0.0/gems/unicode-emoji-4.2.0/MIT-LICENSE.txt +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/unicode-emoji-4.2.0/README.md +205 -0
- data/vendor/bundle/ruby/4.0.0/gems/uri-1.1.1/README.md +55 -0
- data/vendor/bundle/ruby/4.0.0/gems/webmock-3.26.2/CHANGELOG.md +2148 -0
- data/vendor/bundle/ruby/4.0.0/gems/webmock-3.26.2/LICENSE +20 -0
- data/vendor/bundle/ruby/4.0.0/gems/webmock-3.26.2/README.md +1229 -0
- metadata +171 -4
- data/doc/file.README.html +0 -192
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# MessagePack
|
|
2
|
+
|
|
3
|
+
[MessagePack](http://msgpack.org) is an efficient binary serialization format.
|
|
4
|
+
It lets you exchange data among multiple languages like JSON but it's faster and smaller.
|
|
5
|
+
For example, small integers (like flags or error code) are encoded into a single byte,
|
|
6
|
+
and typical short strings only require an extra byte in addition to the strings themselves.
|
|
7
|
+
|
|
8
|
+
If you ever wished to use JSON for convenience (storing an image with metadata) but could
|
|
9
|
+
not for technical reasons (binary data, size, speed...), MessagePack is a perfect replacement.
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
require 'msgpack'
|
|
13
|
+
msg = [1,2,3].to_msgpack #=> "\x93\x01\x02\x03"
|
|
14
|
+
MessagePack.unpack(msg) #=> [1,2,3]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Add msgpack to your Gemfile to install with Bundler:
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
# Gemfile
|
|
21
|
+
gem 'msgpack'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or, use RubyGems to install:
|
|
25
|
+
|
|
26
|
+
gem install msgpack
|
|
27
|
+
|
|
28
|
+
Or, build msgpack-ruby and install from a checked-out msgpack-ruby repository:
|
|
29
|
+
|
|
30
|
+
bundle
|
|
31
|
+
rake
|
|
32
|
+
gem install --local pkg/msgpack
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
## Use cases
|
|
36
|
+
|
|
37
|
+
* Create REST API returing MessagePack using Rails + [RABL](https://github.com/nesquena/rabl)
|
|
38
|
+
* Store objects efficiently serialized by msgpack on memcached or Redis
|
|
39
|
+
* In fact Redis supports msgpack in [EVAL-scripts](https://redis.io/docs/latest/commands/eval/)
|
|
40
|
+
* Upload data in efficient format from mobile devices such as smartphones
|
|
41
|
+
* MessagePack works on iPhone/iPad and Android. See also [Objective-C](https://github.com/msgpack/msgpack-objectivec) and [Java](https://github.com/msgpack/msgpack-java) implementations
|
|
42
|
+
* Design a portable protocol to communicate with embedded devices
|
|
43
|
+
* Check also [Fluentd](https://www.fluentd.org) which is a log collector which uses msgpack for the log format (they say it uses JSON but actually it's msgpack, which is compatible with JSON)
|
|
44
|
+
* Exchange objects between software components written in different languages
|
|
45
|
+
* You'll need a flexible but efficient format so that components exchange objects while keeping compatibility
|
|
46
|
+
|
|
47
|
+
## Portability
|
|
48
|
+
|
|
49
|
+
MessagePack for Ruby should run on x86, ARM, PowerPC, SPARC and other CPU architectures.
|
|
50
|
+
|
|
51
|
+
And it works with MRI (CRuby) and Rubinius.
|
|
52
|
+
Patches to improve portability are highly welcomed.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
## Serializing objects
|
|
56
|
+
|
|
57
|
+
Use `MessagePack.pack` or `to_msgpack`:
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
require 'msgpack'
|
|
61
|
+
msg = MessagePack.pack(obj) # or
|
|
62
|
+
msg = obj.to_msgpack
|
|
63
|
+
File.binwrite('mydata.msgpack', msg)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Streaming serialization
|
|
67
|
+
|
|
68
|
+
Packer provides advanced API to serialize objects in streaming style:
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
# serialize a 2-element array [e1, e2]
|
|
72
|
+
pk = MessagePack::Packer.new(io)
|
|
73
|
+
pk.write_array_header(2).write(e1).write(e2).flush
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
See [API reference](http://ruby.msgpack.org/MessagePack/Packer.html) for details.
|
|
77
|
+
|
|
78
|
+
## Deserializing objects
|
|
79
|
+
|
|
80
|
+
Use `MessagePack.unpack`:
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
require 'msgpack'
|
|
84
|
+
msg = File.binread('mydata.msgpack')
|
|
85
|
+
obj = MessagePack.unpack(msg)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Streaming deserialization
|
|
89
|
+
|
|
90
|
+
Unpacker provides advanced API to deserialize objects in streaming style:
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
# deserialize objects from an IO
|
|
94
|
+
u = MessagePack::Unpacker.new(io)
|
|
95
|
+
u.each do |obj|
|
|
96
|
+
# ...
|
|
97
|
+
end
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
or event-driven style which works well with EventMachine:
|
|
101
|
+
|
|
102
|
+
```ruby
|
|
103
|
+
# event-driven deserialization
|
|
104
|
+
def on_read(data)
|
|
105
|
+
@u ||= MessagePack::Unpacker.new
|
|
106
|
+
@u.feed_each(data) {|obj|
|
|
107
|
+
# ...
|
|
108
|
+
}
|
|
109
|
+
end
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
See [API reference](http://ruby.msgpack.org/MessagePack/Unpacker.html) for details.
|
|
113
|
+
|
|
114
|
+
## Serializing and deserializing symbols
|
|
115
|
+
|
|
116
|
+
By default, symbols are serialized as strings:
|
|
117
|
+
|
|
118
|
+
```ruby
|
|
119
|
+
packed = :symbol.to_msgpack # => "\xA6symbol"
|
|
120
|
+
MessagePack.unpack(packed) # => "symbol"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
This can be customized by registering an extension type for them:
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
MessagePack::DefaultFactory.register_type(0x00, Symbol)
|
|
127
|
+
|
|
128
|
+
# symbols now survive round trips
|
|
129
|
+
packed = :symbol.to_msgpack # => "\xc7\x06\x00symbol"
|
|
130
|
+
MessagePack.unpack(packed) # => :symbol
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The extension type for symbols is configurable like any other extension type.
|
|
134
|
+
For example, to customize how symbols are packed you can just redefine
|
|
135
|
+
Symbol#to_msgpack_ext. Doing this gives you an option to prevent symbols from
|
|
136
|
+
being serialized altogether by throwing an exception:
|
|
137
|
+
|
|
138
|
+
```ruby
|
|
139
|
+
class Symbol
|
|
140
|
+
def to_msgpack_ext
|
|
141
|
+
raise "Serialization of symbols prohibited"
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
MessagePack::DefaultFactory.register_type(0x00, Symbol)
|
|
146
|
+
|
|
147
|
+
[1, :symbol, 'string'].to_msgpack # => RuntimeError: Serialization of symbols prohibited
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Serializing and deserializing Time instances
|
|
151
|
+
|
|
152
|
+
There are the timestamp extension type in MessagePack,
|
|
153
|
+
but it is not registered by default.
|
|
154
|
+
|
|
155
|
+
To map Ruby's Time to MessagePack's timestamp for the default factory:
|
|
156
|
+
|
|
157
|
+
```ruby
|
|
158
|
+
MessagePack::DefaultFactory.register_type(
|
|
159
|
+
MessagePack::Timestamp::TYPE, # or just -1
|
|
160
|
+
Time,
|
|
161
|
+
packer: MessagePack::Time::Packer,
|
|
162
|
+
unpacker: MessagePack::Time::Unpacker
|
|
163
|
+
)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
See [API reference](http://ruby.msgpack.org/) for details.
|
|
167
|
+
|
|
168
|
+
## Extension Types
|
|
169
|
+
|
|
170
|
+
Packer and Unpacker support [Extension types of MessagePack](https://github.com/msgpack/msgpack/blob/master/spec.md#types-extension-type).
|
|
171
|
+
|
|
172
|
+
```ruby
|
|
173
|
+
# register how to serialize custom class at first
|
|
174
|
+
pk = MessagePack::Packer.new(io)
|
|
175
|
+
pk.register_type(0x01, MyClass1, :to_msgpack_ext) # equal to pk.register_type(0x01, MyClass)
|
|
176
|
+
pk.register_type(0x02, MyClass2){|obj| obj.how_to_serialize() } # blocks also available
|
|
177
|
+
|
|
178
|
+
# almost same API for unpacker
|
|
179
|
+
uk = MessagePack::Unpacker.new()
|
|
180
|
+
uk.register_type(0x01, MyClass1, :from_msgpack_ext)
|
|
181
|
+
uk.register_type(0x02){|data| MyClass2.create_from_serialized_data(data) }
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
`MessagePack::Factory` is to create packer and unpacker which have same extension types.
|
|
185
|
+
|
|
186
|
+
```ruby
|
|
187
|
+
factory = MessagePack::Factory.new
|
|
188
|
+
factory.register_type(0x01, MyClass1) # same with next line
|
|
189
|
+
factory.register_type(0x01, MyClass1, packer: :to_msgpack_ext, unpacker: :from_msgpack_ext)
|
|
190
|
+
pk = factory.packer(options_for_packer)
|
|
191
|
+
uk = factory.unpacker(options_for_unpacker)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
For `MessagePack.pack` and `MessagePack.unpack`, default packer/unpacker refer `MessagePack::DefaultFactory`. Call `MessagePack::DefaultFactory.register_type` to enable types process globally.
|
|
195
|
+
|
|
196
|
+
```ruby
|
|
197
|
+
MessagePack::DefaultFactory.register_type(0x03, MyClass3)
|
|
198
|
+
MessagePack.unpack(data_with_ext_typeid_03) #=> MyClass3 instance
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Alternatively, extension types can call the packer or unpacker recursively to generate the extension data:
|
|
202
|
+
|
|
203
|
+
```ruby
|
|
204
|
+
Point = Struct.new(:x, :y)
|
|
205
|
+
factory = MessagePack::Factory.new
|
|
206
|
+
factory.register_type(
|
|
207
|
+
0x01,
|
|
208
|
+
Point,
|
|
209
|
+
packer: ->(point, packer) {
|
|
210
|
+
packer.write(point.x)
|
|
211
|
+
packer.write(point.y)
|
|
212
|
+
},
|
|
213
|
+
unpacker: ->(unpacker) {
|
|
214
|
+
x = unpacker.read
|
|
215
|
+
y = unpacker.read
|
|
216
|
+
Point.new(x, y)
|
|
217
|
+
},
|
|
218
|
+
recursive: true,
|
|
219
|
+
)
|
|
220
|
+
factory.load(factory.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Pooling
|
|
224
|
+
|
|
225
|
+
Creating `Packer` and `Unpacker` objects is expensive. For best performance it is preferable to re-use these objects.
|
|
226
|
+
|
|
227
|
+
`MessagePack::Factory#pool` makes that easier:
|
|
228
|
+
|
|
229
|
+
```ruby
|
|
230
|
+
factory = MessagePack::Factory.new
|
|
231
|
+
factory.register_type(
|
|
232
|
+
0x01,
|
|
233
|
+
Point,
|
|
234
|
+
packer: ->(point, packer) {
|
|
235
|
+
packer.write(point.x)
|
|
236
|
+
packer.write(point.y)
|
|
237
|
+
},
|
|
238
|
+
unpacker: ->(unpacker) {
|
|
239
|
+
x = unpacker.read
|
|
240
|
+
y = unpacker.read
|
|
241
|
+
Point.new(x, y)
|
|
242
|
+
},
|
|
243
|
+
recursive: true,
|
|
244
|
+
)
|
|
245
|
+
pool = factory.pool(5) # The pool size should match the number of threads expected to use the factory concurrently.
|
|
246
|
+
|
|
247
|
+
pool.load(pool.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Buffer API
|
|
251
|
+
|
|
252
|
+
MessagePack for Ruby provides a buffer API so that you can read or write data by hand, not via Packer or Unpacker API.
|
|
253
|
+
|
|
254
|
+
This [MessagePack::Buffer](http://ruby.msgpack.org/MessagePack/Buffer.html) is backed with a fixed-length shared memory pool which is very fast for small data (<= 4KB),
|
|
255
|
+
and has zero-copy capability which significantly affects performance to handle large binary data.
|
|
256
|
+
|
|
257
|
+
## How to build and run tests
|
|
258
|
+
|
|
259
|
+
Before building msgpack, you need to install bundler and dependencies.
|
|
260
|
+
|
|
261
|
+
gem install bundler
|
|
262
|
+
bundle install
|
|
263
|
+
|
|
264
|
+
Then, you can run the tasks as follows:
|
|
265
|
+
|
|
266
|
+
### Build
|
|
267
|
+
|
|
268
|
+
bundle exec rake build
|
|
269
|
+
|
|
270
|
+
### Run tests
|
|
271
|
+
|
|
272
|
+
bundle exec rake spec
|
|
273
|
+
|
|
274
|
+
### Generating docs
|
|
275
|
+
|
|
276
|
+
bundle exec rake doc
|
|
277
|
+
|
|
278
|
+
## How to build -java rubygems
|
|
279
|
+
|
|
280
|
+
To build -java gems for JRuby, run:
|
|
281
|
+
|
|
282
|
+
rake build:java
|
|
283
|
+
|
|
284
|
+
If this directory has Gemfile.lock (generated with MRI), remove it beforehand.
|
|
285
|
+
|
|
286
|
+
## Updating documents
|
|
287
|
+
|
|
288
|
+
Online documentation (https://ruby.msgpack.org) is generated from the gh-pages branch.
|
|
289
|
+
To update documents in gh-pages branch:
|
|
290
|
+
|
|
291
|
+
bundle exec rake doc
|
|
292
|
+
git checkout gh-pages
|
|
293
|
+
cp -a doc/* ./
|
|
294
|
+
|
|
295
|
+
## Copyright
|
|
296
|
+
|
|
297
|
+
* Author
|
|
298
|
+
* Sadayuki Furuhashi <frsyuki@gmail.com>
|
|
299
|
+
* Copyright
|
|
300
|
+
* Copyright (c) 2008-2015 Sadayuki Furuhashi
|
|
301
|
+
* License
|
|
302
|
+
* Apache License, Version 2.0
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) 2010-2026 Erik Berlin, Michael Bleigh, Josh Kalderimis, Pavel Pravosud
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# MultiJSON
|
|
2
|
+
|
|
3
|
+
[][tests]
|
|
4
|
+
[][linter]
|
|
5
|
+
[][mutant]
|
|
6
|
+
[][typecheck]
|
|
7
|
+
[][docs]
|
|
8
|
+
[][qlty]
|
|
9
|
+
[][gem]
|
|
10
|
+
|
|
11
|
+
Lots of Ruby libraries parse JSON and everyone has their favorite JSON coder.
|
|
12
|
+
Instead of choosing a single JSON coder and forcing users of your library to be
|
|
13
|
+
stuck with it, you can use MultiJSON instead, which will simply choose the
|
|
14
|
+
fastest available JSON coder. Here's how to use it:
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
require "multi_json"
|
|
18
|
+
|
|
19
|
+
MultiJSON.parse('{"abc":"def"}') #=> {"abc" => "def"}
|
|
20
|
+
MultiJSON.parse('{"abc":"def"}', symbolize_names: true) #=> {abc: "def"}
|
|
21
|
+
MultiJSON.generate({abc: "def"}) # convert Ruby back to JSON
|
|
22
|
+
MultiJSON.generate({abc: "def"}, pretty: true) # encoded in a pretty form (if supported by the coder)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
> [!IMPORTANT]
|
|
26
|
+
> **1.21.0 renames the public API to match Ruby stdlib `JSON`.** The canonical
|
|
27
|
+
> verbs are now `MultiJSON.parse` / `MultiJSON.generate`, and the canonical
|
|
28
|
+
> module is `MultiJSON` (all-caps). The legacy `MultiJson` constant,
|
|
29
|
+
> `MultiJSON.load` / `MultiJSON.dump`, `:symbolize_keys`, and friends still
|
|
30
|
+
> work but emit one-time deprecation warnings and **will be removed in 2.0.0**.
|
|
31
|
+
> Run your app with `ruby -W:deprecated` to surface them; the warnings are
|
|
32
|
+
> tagged with the `:deprecated` category so you can silence the whole set with
|
|
33
|
+
> `Warning[:deprecated] = false`. See [Deprecated in 1.21.0](#deprecated-in-1210)
|
|
34
|
+
> for the full list.
|
|
35
|
+
|
|
36
|
+
`MultiJSON.parse` returns `nil` for `nil`, empty, and whitespace-only inputs
|
|
37
|
+
instead of raising, so a missing or blank payload is observable as a `nil`
|
|
38
|
+
return value rather than an exception. When parsing invalid JSON, MultiJSON
|
|
39
|
+
will throw a `MultiJSON::ParseError`. `MultiJSON::DecodeError` and
|
|
40
|
+
`MultiJSON::LoadError` are aliases for backwards compatibility.
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
begin
|
|
44
|
+
MultiJSON.parse("{invalid json}")
|
|
45
|
+
rescue MultiJSON::ParseError => exception
|
|
46
|
+
exception.data #=> "{invalid json}"
|
|
47
|
+
exception.cause #=> JSON::ParserError: ...
|
|
48
|
+
exception.line #=> 1 (for adapters that report a location, e.g. Oj or the json gem)
|
|
49
|
+
exception.column #=> 2
|
|
50
|
+
end
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Drop-in replacement for stdlib `JSON`
|
|
54
|
+
|
|
55
|
+
MultiJSON mirrors the surface of Ruby's stdlib [`JSON`][json-gem] so
|
|
56
|
+
most call sites swap in with a one-line change:
|
|
57
|
+
|
|
58
|
+
```diff
|
|
59
|
+
- require "json"
|
|
60
|
+
+ require "multi_json"
|
|
61
|
+
|
|
62
|
+
- JSON.parse(text, symbolize_names: true)
|
|
63
|
+
+ MultiJSON.parse(text, symbolize_names: true)
|
|
64
|
+
|
|
65
|
+
- JSON.generate(object, pretty: true)
|
|
66
|
+
+ MultiJSON.generate(object, pretty: true)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Method names and the common options line up with stdlib so existing
|
|
70
|
+
pretty-print calls and option keys keep working without changes:
|
|
71
|
+
|
|
72
|
+
| stdlib `JSON` | `MultiJSON` | Status |
|
|
73
|
+
| ---------------------- | -------------------------- | :---: |
|
|
74
|
+
| `JSON.parse(str)` | `MultiJSON.parse(str)` | ✓ |
|
|
75
|
+
| `JSON.generate(obj)` | `MultiJSON.generate(obj)` | ✓ |
|
|
76
|
+
| `pretty: true` | `pretty: true` | ✓ |
|
|
77
|
+
| `symbolize_names: true` | `symbolize_names: true` | ✓ |
|
|
78
|
+
|
|
79
|
+
### Deprecated in 1.21.0
|
|
80
|
+
|
|
81
|
+
The module constant and primary verbs were renamed to match Ruby
|
|
82
|
+
stdlib `JSON.parse` / `JSON.generate` and the JSON spec (RFC 8259).
|
|
83
|
+
The old names still work in 1.x but now emit a one-time deprecation
|
|
84
|
+
warning; **they will be removed in 2.0.0**.
|
|
85
|
+
|
|
86
|
+
| Deprecated | Use instead |
|
|
87
|
+
| ----------------------------- | ------------------------------- |
|
|
88
|
+
| `MultiJson` (constant) | `MultiJSON` (all-caps) |
|
|
89
|
+
| `MultiJSON.load(str)` | `MultiJSON.parse(str)` |
|
|
90
|
+
| `MultiJSON.dump(obj)` | `MultiJSON.generate(obj)` |
|
|
91
|
+
| `MultiJSON.load_options=` | `MultiJSON.parse_options=` |
|
|
92
|
+
| `MultiJSON.load_options` | `MultiJSON.parse_options` |
|
|
93
|
+
| `MultiJSON.dump_options=` | `MultiJSON.generate_options=` |
|
|
94
|
+
| `MultiJSON.dump_options` | `MultiJSON.generate_options` |
|
|
95
|
+
| `symbolize_keys:` option | `symbolize_names:` option |
|
|
96
|
+
|
|
97
|
+
The `MultiJson` constant (CamelCase) continues to work as a thin
|
|
98
|
+
delegator; every method call, constant lookup, and rescue clause
|
|
99
|
+
routes through `MultiJSON` transparently.
|
|
100
|
+
|
|
101
|
+
> [!TIP]
|
|
102
|
+
> The recommended upgrade path to 2.0 is: pin `~> 1.21` first, run
|
|
103
|
+
> `ruby -W:deprecated` against your app or test suite to surface every
|
|
104
|
+
> deprecation, migrate each call site to the canonical name, then bump to
|
|
105
|
+
> `~> 2.0`. The 2.0 release deletes the deprecated aliases entirely, so the
|
|
106
|
+
> warnings during 1.21.x are your map.
|
|
107
|
+
|
|
108
|
+
`ParseError` instance has `cause` reader which contains the original exception.
|
|
109
|
+
It also has `data` reader with the input that caused the problem, and `line`/`column`
|
|
110
|
+
readers populated for adapters whose error messages include a location (Oj and the
|
|
111
|
+
json gem). Adapters that don't include one (Yajl, fast_jsonparser) leave both nil.
|
|
112
|
+
|
|
113
|
+
### Tuning the options cache
|
|
114
|
+
|
|
115
|
+
MultiJSON memoizes the merged option hash for each `parse`/`generate` call so
|
|
116
|
+
identical option hashes don't trigger repeated work. The cache is bounded —
|
|
117
|
+
defaulting to 1000 entries per direction — and applications that generate many
|
|
118
|
+
distinct option hashes can raise the ceiling at runtime:
|
|
119
|
+
|
|
120
|
+
```ruby
|
|
121
|
+
MultiJSON::OptionsCache.max_cache_size = 5000
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`max_cache_size` must be a positive integer; `0`, negative values, and
|
|
125
|
+
non-integers raise `ArgumentError`.
|
|
126
|
+
|
|
127
|
+
Lowering the limit only takes effect for *new* inserts; existing cache
|
|
128
|
+
entries are left in place until normal eviction trims them below the
|
|
129
|
+
new ceiling. Call `MultiJSON::OptionsCache.reset` if you want to evict
|
|
130
|
+
immediately.
|
|
131
|
+
|
|
132
|
+
The `use` method, which sets the MultiJSON adapter, takes either a symbol or a
|
|
133
|
+
class (to allow for custom JSON parsers) that responds to both `.load` and `.dump`
|
|
134
|
+
at the class level.
|
|
135
|
+
|
|
136
|
+
When MultiJSON fails to load the specified adapter, it'll throw `MultiJSON::AdapterError`
|
|
137
|
+
which inherits from `ArgumentError`.
|
|
138
|
+
|
|
139
|
+
### Writing a custom adapter
|
|
140
|
+
|
|
141
|
+
A custom adapter is any class that responds to two class methods plus
|
|
142
|
+
defines a `ParseError` constant:
|
|
143
|
+
|
|
144
|
+
```ruby
|
|
145
|
+
class MyAdapter
|
|
146
|
+
ParseError = Class.new(StandardError)
|
|
147
|
+
|
|
148
|
+
def self.load(string, options)
|
|
149
|
+
# parse string into a Ruby object, raising ParseError on failure
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def self.dump(object, options)
|
|
153
|
+
# serialize object to a JSON string
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
MultiJSON.use(MyAdapter)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`ParseError` is required: `MultiJSON.parse` rescues `MyAdapter::ParseError`
|
|
161
|
+
to wrap parse failures in `MultiJSON::ParseError`, and an adapter that
|
|
162
|
+
omits the constant raises `MultiJSON::AdapterError` on the first parse
|
|
163
|
+
attempt instead of producing a confusing `NameError`.
|
|
164
|
+
|
|
165
|
+
For more, inherit from `MultiJSON::Adapter` to pick up shared option
|
|
166
|
+
merging, the `defaults :load, ...` / `defaults :dump, ...` DSL, and the
|
|
167
|
+
blank-input short-circuit. The built-in adapters in
|
|
168
|
+
`lib/multi_json/adapters/` are working examples.
|
|
169
|
+
|
|
170
|
+
> [!NOTE]
|
|
171
|
+
> The adapter contract methods on the adapter class itself stay named
|
|
172
|
+
> `.load` / `.dump` in 1.21.x (and the `defaults :load, ...` / `defaults
|
|
173
|
+
> :dump, ...` DSL keys match). The 2.0 release renames them to `.parse` /
|
|
174
|
+
> `.generate` to align with the public API; if you ship a custom adapter,
|
|
175
|
+
> you'll need to rename those methods (and the `defaults` keys) when you
|
|
176
|
+
> upgrade.
|
|
177
|
+
|
|
178
|
+
MultiJSON tries to have intelligent defaulting. If any supported library is
|
|
179
|
+
already loaded, MultiJSON uses it before attempting to load others. When no
|
|
180
|
+
backend is preloaded, MultiJSON walks its preference list and uses the first
|
|
181
|
+
one that loads successfully. The list is split per platform — JRuby's
|
|
182
|
+
available adapter set differs from MRI's, and the bundled benchmark suite
|
|
183
|
+
ranks `json_gem` ahead of `fast_jsonparser`/`oj`/`yajl` on Ruby 3.4+. CI
|
|
184
|
+
re-runs the benchmark and fails if the observed ranking diverges from the
|
|
185
|
+
table below.
|
|
186
|
+
|
|
187
|
+
| rank | MRI / TruffleRuby | JRuby |
|
|
188
|
+
| ---- | ----------------- | --------------- |
|
|
189
|
+
| 1 | The JSON gem | `jrjackson` |
|
|
190
|
+
| 2 | `fast_jsonparser` | The JSON gem |
|
|
191
|
+
| 3 | `oj` | `gson` |
|
|
192
|
+
| 4 | `yajl-ruby` | — |
|
|
193
|
+
|
|
194
|
+
A dash means the adapter isn't usable on that runtime: `fast_jsonparser`,
|
|
195
|
+
`oj`, and `yajl-ruby` are MRI/TruffleRuby C extensions with no JRuby builds;
|
|
196
|
+
`jrjackson` and `gson` are JRuby-only. The JSON gem is a Ruby default gem,
|
|
197
|
+
so it's always available as a last-resort fallback on any supported Ruby.
|
|
198
|
+
If you have a workload where a different backend is faster, set it
|
|
199
|
+
explicitly with `MultiJSON.use(:your_adapter)`.
|
|
200
|
+
|
|
201
|
+
## Gem Variants
|
|
202
|
+
|
|
203
|
+
MultiJSON ships as two platform-specific gems. Bundler and RubyGems
|
|
204
|
+
automatically select the correct variant for your Ruby implementation:
|
|
205
|
+
|
|
206
|
+
| | `ruby` platform (MRI) | `java` platform (JRuby) |
|
|
207
|
+
| ---------------------------------------------- | :---: | :---: |
|
|
208
|
+
| Runtime dependency | none | [concurrent-ruby][concurrent-ruby] `~> 1.2` |
|
|
209
|
+
| [`fast_jsonparser`][fast_jsonparser] adapter | ✓ | |
|
|
210
|
+
| [`oj`][oj] adapter | ✓ | |
|
|
211
|
+
| [`yajl`][yajl] adapter | ✓ | |
|
|
212
|
+
| [`json_gem`][json-gem] adapter | ✓ | ✓ |
|
|
213
|
+
| [`gson`][gson] adapter | | ✓ |
|
|
214
|
+
| [`jr_jackson`][jrjackson] adapter | | ✓ |
|
|
215
|
+
| `OptionsCache` thread-safe store | `Hash` + `Mutex` | `Concurrent::Map` |
|
|
216
|
+
|
|
217
|
+
## Supported Ruby Versions
|
|
218
|
+
|
|
219
|
+
This library aims to support and is [tested against](https://github.com/sferik/multi_json/actions/workflows/tests.yml) the following Ruby
|
|
220
|
+
implementations:
|
|
221
|
+
|
|
222
|
+
- Ruby 3.2
|
|
223
|
+
- Ruby 3.3
|
|
224
|
+
- Ruby 3.4
|
|
225
|
+
- Ruby 4.0
|
|
226
|
+
- [JRuby][jruby] 10.0 (targets Ruby 3.4 compatibility)
|
|
227
|
+
- [TruffleRuby][truffleruby] 33.0 (native and JVM)
|
|
228
|
+
|
|
229
|
+
If something doesn't work in one of these implementations, it's a bug.
|
|
230
|
+
|
|
231
|
+
This library may inadvertently work (or seem to work) on other Ruby
|
|
232
|
+
implementations, however support will only be provided for the versions listed
|
|
233
|
+
above.
|
|
234
|
+
|
|
235
|
+
If you would like this library to support another Ruby version, you may
|
|
236
|
+
volunteer to be a maintainer. Being a maintainer entails making sure all tests
|
|
237
|
+
run and pass on that implementation. When something breaks on your
|
|
238
|
+
implementation, you will be responsible for providing patches in a timely
|
|
239
|
+
fashion. If critical issues for a particular implementation exist at the time
|
|
240
|
+
of a major release, support for that Ruby version may be dropped.
|
|
241
|
+
|
|
242
|
+
## Versioning
|
|
243
|
+
|
|
244
|
+
This library aims to adhere to [Semantic Versioning 2.0.0][semver]. Violations
|
|
245
|
+
of this scheme should be reported as bugs. Specifically, if a minor or patch
|
|
246
|
+
version is released that breaks backward compatibility, that version should be
|
|
247
|
+
immediately yanked and/or a new version should be immediately released that
|
|
248
|
+
restores compatibility. Breaking changes to the public API will only be
|
|
249
|
+
introduced with new major versions. As a result of this policy, you can (and
|
|
250
|
+
should) specify a dependency on this gem using the [Pessimistic Version
|
|
251
|
+
Constraint][pvc] with two digits of precision. For example:
|
|
252
|
+
|
|
253
|
+
```ruby
|
|
254
|
+
spec.add_dependency 'multi_json', '~> 1.0'
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Copyright
|
|
258
|
+
|
|
259
|
+
Copyright (c) 2010-2026 Erik Berlin, Michael Bleigh, Josh Kalderimis, and Pavel
|
|
260
|
+
Pravosud. See [LICENSE][license] for details.
|
|
261
|
+
|
|
262
|
+
[concurrent-ruby]: https://github.com/ruby-concurrency/concurrent-ruby
|
|
263
|
+
[docs]: https://github.com/sferik/multi_json/actions/workflows/docs.yml
|
|
264
|
+
[fast_jsonparser]: https://github.com/anilmaurya/fast_jsonparser
|
|
265
|
+
[gem]: https://rubygems.org/gems/multi_json
|
|
266
|
+
[gson]: https://github.com/avsej/gson.rb
|
|
267
|
+
[jrjackson]: https://github.com/guyboertje/jrjackson
|
|
268
|
+
[jruby]: http://www.jruby.org/
|
|
269
|
+
[json-gem]: https://github.com/flori/json
|
|
270
|
+
[license]: LICENSE.md
|
|
271
|
+
[linter]: https://github.com/sferik/multi_json/actions/workflows/linter.yml
|
|
272
|
+
[macruby]: http://www.macruby.org/
|
|
273
|
+
[mutant]: https://github.com/sferik/multi_json/actions/workflows/mutant.yml
|
|
274
|
+
[oj]: https://github.com/ohler55/oj
|
|
275
|
+
[pvc]: http://docs.rubygems.org/read/chapter/16#page74
|
|
276
|
+
[qlty]: https://qlty.sh/gh/sferik/projects/multi_json
|
|
277
|
+
[semver]: http://semver.org/
|
|
278
|
+
[tests]: https://github.com/sferik/multi_json/actions/workflows/tests.yml
|
|
279
|
+
[truffleruby]: https://www.graalvm.org/ruby/
|
|
280
|
+
[typecheck]: https://github.com/sferik/multi_json/actions/workflows/typecheck.yml
|
|
281
|
+
[yajl]: https://github.com/brianmario/yajl-ruby
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
All files in libev are
|
|
2
|
+
Copyright (c)2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions are
|
|
6
|
+
met:
|
|
7
|
+
|
|
8
|
+
* Redistributions of source code must retain the above copyright
|
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
* Redistributions in binary form must reproduce the above
|
|
12
|
+
copyright notice, this list of conditions and the following
|
|
13
|
+
disclaimer in the documentation and/or other materials provided
|
|
14
|
+
with the distribution.
|
|
15
|
+
|
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
17
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
18
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
19
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
20
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
21
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
22
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
23
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
24
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
25
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
26
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
|
|
28
|
+
Alternatively, the contents of this package may be used under the terms
|
|
29
|
+
of the GNU General Public License ("GPL") version 2 or any later version,
|
|
30
|
+
in which case the provisions of the GPL are applicable instead of the
|
|
31
|
+
above. If you wish to allow the use of your version of this package only
|
|
32
|
+
under the terms of the GPL and not to allow others to use your version of
|
|
33
|
+
this file under the BSD license, indicate your decision by deleting the
|
|
34
|
+
provisions above and replace them with the notice and other provisions
|
|
35
|
+
required by the GPL in this and the other files of this package. If you do
|
|
36
|
+
not delete the provisions above, a recipient may use your version of this
|
|
37
|
+
file under either the BSD or the GPL.
|