paquito 0.3.0 → 0.5.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/.github/workflows/ci.yml +16 -1
- data/.rubocop.yml +1 -1
- data/Gemfile +4 -3
- data/Gemfile.lock +29 -25
- data/README.md +14 -13
- data/Rakefile +2 -1
- data/benchmark/msgpack-pooling.rb +19 -0
- data/dev.yml +1 -1
- data/lib/paquito/active_record_coder.rb +5 -4
- data/lib/paquito/allow_nil.rb +2 -0
- data/lib/paquito/codec_factory.rb +21 -8
- data/lib/paquito/safe_yaml.rb +22 -15
- data/lib/paquito/typed_struct.rb +1 -0
- data/lib/paquito/types.rb +45 -14
- data/lib/paquito/version.rb +1 -1
- data/paquito.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6fef6b415e3f3f99d82d937b412923f77675f2fd2b458c67a79b17325df5c4b
|
4
|
+
data.tar.gz: a3805612f06f9a04a2c3c452f571798d086113ff601ee550623e975abd66ac15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76457976e3d2bbf665b38922d0e9be0d62bfa7ecb34e7a55c3931eff29260646a92e7b5f6ed04ff53a350cc035c4e794e9a079be39cb95b1f6f261211db94a2e
|
7
|
+
data.tar.gz: ed1156971e6736ee6b9abab62edb2b6eabb5ad1751a3d6d2aa48b84c444b5720dc21ba713721f82c10a7f0cbf629520ef0bc1e8625702afc683494b4fd940e22
|
data/.github/workflows/ci.yml
CHANGED
@@ -3,12 +3,27 @@ name: CI
|
|
3
3
|
on: [push, pull_request]
|
4
4
|
|
5
5
|
jobs:
|
6
|
+
rubocop:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
steps:
|
11
|
+
- name: Checkout
|
12
|
+
uses: actions/checkout@v2
|
13
|
+
- name: Set up Ruby
|
14
|
+
uses: ruby/setup-ruby@v1
|
15
|
+
with:
|
16
|
+
ruby-version: '2.6'
|
17
|
+
bundler-cache: true
|
18
|
+
- name: Run test
|
19
|
+
run: bundle exec rubocop
|
20
|
+
|
6
21
|
rubies:
|
7
22
|
runs-on: ubuntu-latest
|
8
23
|
strategy:
|
9
24
|
fail-fast: false
|
10
25
|
matrix:
|
11
|
-
ruby: [ ruby-head, '3.0', '2.7' ]
|
26
|
+
ruby: [ ruby-head, '3.0', '2.7', '2.6' ]
|
12
27
|
steps:
|
13
28
|
- name: Checkout
|
14
29
|
uses: actions/checkout@v2
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
@@ -5,12 +5,13 @@ source "https://rubygems.org"
|
|
5
5
|
# Specify your gem's dependencies in paquito.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem "msgpack", github: "msgpack/msgpack-ruby"
|
8
|
+
gem "msgpack", github: "msgpack/msgpack-ruby"
|
9
9
|
|
10
10
|
gem "rake", "~> 13.0"
|
11
|
-
gem "activesupport"
|
12
|
-
gem "activerecord"
|
11
|
+
gem "activesupport"
|
12
|
+
gem "activerecord"
|
13
13
|
gem "sqlite3"
|
14
|
+
gem "benchmark-ips"
|
14
15
|
|
15
16
|
gem "minitest", "~> 5.0"
|
16
17
|
|
data/Gemfile.lock
CHANGED
@@ -1,60 +1,63 @@
|
|
1
1
|
GIT
|
2
2
|
remote: https://github.com/msgpack/msgpack-ruby.git
|
3
|
-
revision:
|
3
|
+
revision: b69e6d6965ef46890885ddf73f02b820f3185d80
|
4
4
|
specs:
|
5
|
-
msgpack (1.4.
|
5
|
+
msgpack (1.4.5)
|
6
6
|
|
7
7
|
PATH
|
8
8
|
remote: .
|
9
9
|
specs:
|
10
|
-
paquito (0.
|
10
|
+
paquito (0.5.0)
|
11
11
|
msgpack
|
12
12
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
|
-
activemodel (
|
17
|
-
activesupport (=
|
18
|
-
activerecord (
|
19
|
-
activemodel (=
|
20
|
-
activesupport (=
|
21
|
-
activesupport (
|
16
|
+
activemodel (6.1.5)
|
17
|
+
activesupport (= 6.1.5)
|
18
|
+
activerecord (6.1.5)
|
19
|
+
activemodel (= 6.1.5)
|
20
|
+
activesupport (= 6.1.5)
|
21
|
+
activesupport (6.1.5)
|
22
22
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
23
23
|
i18n (>= 1.6, < 2)
|
24
24
|
minitest (>= 5.1)
|
25
25
|
tzinfo (~> 2.0)
|
26
|
+
zeitwerk (~> 2.3)
|
26
27
|
ast (2.4.2)
|
28
|
+
benchmark-ips (2.10.0)
|
27
29
|
byebug (11.1.3)
|
28
30
|
concurrent-ruby (1.1.9)
|
29
|
-
i18n (1.
|
31
|
+
i18n (1.10.0)
|
30
32
|
concurrent-ruby (~> 1.0)
|
31
|
-
minitest (5.
|
33
|
+
minitest (5.15.0)
|
32
34
|
parallel (1.21.0)
|
33
|
-
parser (3.
|
35
|
+
parser (3.1.1.0)
|
34
36
|
ast (~> 2.4.1)
|
35
|
-
rainbow (3.
|
37
|
+
rainbow (3.1.1)
|
36
38
|
rake (13.0.6)
|
37
|
-
regexp_parser (2.
|
39
|
+
regexp_parser (2.2.1)
|
38
40
|
rexml (3.2.5)
|
39
|
-
rubocop (1.
|
41
|
+
rubocop (1.25.1)
|
40
42
|
parallel (~> 1.10)
|
41
|
-
parser (>= 3.
|
43
|
+
parser (>= 3.1.0.0)
|
42
44
|
rainbow (>= 2.2.2, < 4.0)
|
43
45
|
regexp_parser (>= 1.8, < 3.0)
|
44
46
|
rexml
|
45
|
-
rubocop-ast (>= 1.
|
47
|
+
rubocop-ast (>= 1.15.1, < 2.0)
|
46
48
|
ruby-progressbar (~> 1.7)
|
47
49
|
unicode-display_width (>= 1.4.0, < 3.0)
|
48
|
-
rubocop-ast (1.
|
49
|
-
parser (>= 3.
|
50
|
-
rubocop-shopify (2.
|
51
|
-
rubocop (~> 1.
|
50
|
+
rubocop-ast (1.16.0)
|
51
|
+
parser (>= 3.1.1.0)
|
52
|
+
rubocop-shopify (2.5.0)
|
53
|
+
rubocop (~> 1.25)
|
52
54
|
ruby-progressbar (1.11.0)
|
53
|
-
sorbet-runtime (0.5.
|
55
|
+
sorbet-runtime (0.5.9742)
|
54
56
|
sqlite3 (1.4.2)
|
55
57
|
tzinfo (2.0.4)
|
56
58
|
concurrent-ruby (~> 1.0)
|
57
59
|
unicode-display_width (2.1.0)
|
60
|
+
zeitwerk (2.5.4)
|
58
61
|
|
59
62
|
PLATFORMS
|
60
63
|
ruby
|
@@ -62,8 +65,9 @@ PLATFORMS
|
|
62
65
|
x86_64-linux
|
63
66
|
|
64
67
|
DEPENDENCIES
|
65
|
-
activerecord
|
66
|
-
activesupport
|
68
|
+
activerecord
|
69
|
+
activesupport
|
70
|
+
benchmark-ips
|
67
71
|
byebug
|
68
72
|
minitest (~> 5.0)
|
69
73
|
msgpack!
|
@@ -75,4 +79,4 @@ DEPENDENCIES
|
|
75
79
|
sqlite3
|
76
80
|
|
77
81
|
BUNDLED WITH
|
78
|
-
2.2.
|
82
|
+
2.2.33
|
data/README.md
CHANGED
@@ -22,7 +22,7 @@ Or install it yourself as:
|
|
22
22
|
|
23
23
|
### `chain`
|
24
24
|
|
25
|
-
`Paquito::CoderChain`
|
25
|
+
`Paquito::CoderChain` combines two or more serializers into one.
|
26
26
|
|
27
27
|
Example:
|
28
28
|
|
@@ -34,7 +34,7 @@ compressed_yaml_coder.load(payload) # => { foo: 42 }
|
|
34
34
|
|
35
35
|
### `ConditionalCompressor`
|
36
36
|
|
37
|
-
`Paquito::ConditionalCompressor`
|
37
|
+
`Paquito::ConditionalCompressor` compresses payloads if they are over a defined size.
|
38
38
|
|
39
39
|
Example:
|
40
40
|
```ruby
|
@@ -45,8 +45,8 @@ coder.dump("foo" * 500) # => "\x01<compressed-data....>"
|
|
45
45
|
|
46
46
|
### `SingleBytePrefixVersion`
|
47
47
|
|
48
|
-
`Paquito::SingleBytePrefixVersion` prepends a version prefix to the payloads, which
|
49
|
-
different serialization methods.
|
48
|
+
`Paquito::SingleBytePrefixVersion` prepends a version prefix to the payloads, which allows you to seamlessly transition
|
49
|
+
between different serialization methods.
|
50
50
|
|
51
51
|
The first argument is the current version used for newly generated payloads.
|
52
52
|
|
@@ -64,9 +64,9 @@ coder.load("\x00---\n:foo: 42") # => { foo: 42 }
|
|
64
64
|
|
65
65
|
### `CommentPrefixVersion`
|
66
66
|
|
67
|
-
Similar to the single byte prefix, but meant to be human readable and to allow for migrating
|
67
|
+
Similar to the single byte prefix, but meant to be human readable and to allow for migrating unversioned payloads.
|
68
68
|
|
69
|
-
|
69
|
+
Payloads without a version prefix are assumed to be version `0`.
|
70
70
|
|
71
71
|
The first argument is the current version used for newly generated payloads.
|
72
72
|
|
@@ -84,7 +84,7 @@ coder.dump([1]) # => "#☠1☢\n[1]"
|
|
84
84
|
|
85
85
|
### `allow_nil`
|
86
86
|
|
87
|
-
In some
|
87
|
+
In some situations where you'd rather not serialize `nil`, you can use the `Paquito.allow_nil` shorthand:
|
88
88
|
|
89
89
|
```ruby
|
90
90
|
coder = Paquito.allow_nil(Marshal)
|
@@ -95,7 +95,7 @@ coder.load(nil) # => nil
|
|
95
95
|
### `TranslateErrors`
|
96
96
|
|
97
97
|
If you do need to handle serialization or deserialization errors, for instance to fallback to acting like a cache miss,
|
98
|
-
`Paquito::TranslateErrors`
|
98
|
+
`Paquito::TranslateErrors` translates all underlying exceptions into `Paquito::Error` descendants.
|
99
99
|
|
100
100
|
Example:
|
101
101
|
|
@@ -117,7 +117,8 @@ coder.load(coder.dump(%i(foo bar).to_set)) # => #<Set: {:foo, :bar}>
|
|
117
117
|
|
118
118
|
### `TypedStruct`
|
119
119
|
|
120
|
-
`Paquito::TypedStruct` is a opt-in Sorbet runtime plugin that allows `T::Struct` classes to be serializable. You need
|
120
|
+
`Paquito::TypedStruct` is a opt-in Sorbet runtime plugin that allows `T::Struct` classes to be serializable. You need
|
121
|
+
to explicitly include the module in the `T::Struct` classes that you will be serializing.
|
121
122
|
|
122
123
|
Example
|
123
124
|
|
@@ -137,12 +138,12 @@ MyStruct.from_pack([26450, "foo", 1]) # => <MyStruct bar=1, foo="foo">
|
|
137
138
|
|
138
139
|
## Rails utilities
|
139
140
|
|
140
|
-
`paquito` doesn't
|
141
|
+
`paquito` doesn't depend on `rails` or any of its components, however it does provide some optional utilities.
|
141
142
|
|
142
143
|
### `CacheEntryCoder`
|
143
144
|
|
144
|
-
`Paquito::CacheEntryCoder` turns an `ActiveSupport::Cache::Entry` instance into a simple `Array` instance. This allows
|
145
|
-
implement custom coders for `ActiveSupport::Cache`.
|
145
|
+
`Paquito::CacheEntryCoder` turns an `ActiveSupport::Cache::Entry` instance into a simple `Array` instance. This allows
|
146
|
+
you to implement custom coders for `ActiveSupport::Cache`.
|
146
147
|
|
147
148
|
Example:
|
148
149
|
|
@@ -152,7 +153,7 @@ ActiveSupport::Cache::FileStore.new("tmp/cache", coder: Paquito.chain(Paquito::C
|
|
152
153
|
|
153
154
|
### `SerializedColumn`
|
154
155
|
|
155
|
-
`Paquito::SerializedColumn` allows to decorate any encoder to behave like Rails's builtin `YAMLColumn`
|
156
|
+
`Paquito::SerializedColumn` allows you to decorate any encoder to behave like Rails's builtin `YAMLColumn`
|
156
157
|
|
157
158
|
Example:
|
158
159
|
|
data/Rakefile
CHANGED
@@ -3,7 +3,8 @@
|
|
3
3
|
require "bundler/gem_tasks"
|
4
4
|
require "rake/testtask"
|
5
5
|
|
6
|
-
suites = [:vanilla, :activesupport
|
6
|
+
suites = [:vanilla, :activesupport]
|
7
|
+
suites << :activerecord if RUBY_VERSION >= "2.7"
|
7
8
|
namespace :test do
|
8
9
|
suites.each do |suite|
|
9
10
|
Rake::TestTask.new(suite) do |t|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "paquito"
|
6
|
+
require "benchmark/ips"
|
7
|
+
|
8
|
+
BASELINE = Paquito::CodecFactory.build([Symbol], pool: false)
|
9
|
+
POOLED = Paquito::CodecFactory.build([Symbol], pool: 1)
|
10
|
+
|
11
|
+
PAYLOAD = BASELINE.dump(:foo)
|
12
|
+
MARSHAL_PAYLOAD = Marshal.dump(:foo)
|
13
|
+
|
14
|
+
Benchmark.ips do |x|
|
15
|
+
x.report("marshal") { Marshal.load(MARSHAL_PAYLOAD) }
|
16
|
+
x.report("msgpack") { BASELINE.load(PAYLOAD) }
|
17
|
+
x.report("pooled") { POOLED.load(PAYLOAD) }
|
18
|
+
x.compare!(order: :baseline)
|
19
|
+
end
|
data/dev.yml
CHANGED
@@ -119,13 +119,14 @@ module Paquito
|
|
119
119
|
@ids = {}.compare_by_identity
|
120
120
|
end
|
121
121
|
|
122
|
-
def map(
|
123
|
-
@instances.map(
|
122
|
+
def map(&block)
|
123
|
+
@instances.map(&block)
|
124
124
|
end
|
125
125
|
|
126
|
-
def fetch(
|
127
|
-
@instances.fetch(
|
126
|
+
def fetch(*args, &block)
|
127
|
+
@instances.fetch(*args, &block)
|
128
128
|
end
|
129
|
+
ruby2_keywords :fetch if respond_to?(:ruby2_keywords, true)
|
129
130
|
|
130
131
|
def push(instance)
|
131
132
|
id = @ids[instance] = @instances.size
|
data/lib/paquito/allow_nil.rb
CHANGED
@@ -5,15 +5,24 @@ require "paquito/coder_chain"
|
|
5
5
|
|
6
6
|
module Paquito
|
7
7
|
class CodecFactory
|
8
|
-
def self.build(types, freeze: false, serializable_type: false)
|
9
|
-
factory =
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
def self.build(types, freeze: false, serializable_type: false, pool: 1)
|
9
|
+
factory = if types.empty? && !serializable_type
|
10
|
+
MessagePack::DefaultFactory
|
11
|
+
else
|
12
|
+
MessagePack::Factory.new
|
13
|
+
end
|
14
|
+
|
15
15
|
Types.register(factory, types) unless types.empty?
|
16
16
|
Types.register_serializable_type(factory) if serializable_type
|
17
|
+
|
18
|
+
if pool && pool > 0 && factory.respond_to?(:pool)
|
19
|
+
if serializable_type || types.any? { |t| Types.recursive?(t) }
|
20
|
+
pool *= 2
|
21
|
+
end
|
22
|
+
factory = factory.freeze.pool(pool, freeze: freeze)
|
23
|
+
freeze = false
|
24
|
+
end
|
25
|
+
|
17
26
|
MessagePackCodec.new(factory, freeze: freeze)
|
18
27
|
end
|
19
28
|
|
@@ -32,7 +41,11 @@ module Paquito
|
|
32
41
|
end
|
33
42
|
|
34
43
|
def load(payload)
|
35
|
-
|
44
|
+
if @freeze
|
45
|
+
@factory.load(payload, freeze: @freeze)
|
46
|
+
else
|
47
|
+
@factory.load(payload)
|
48
|
+
end
|
36
49
|
rescue MessagePack::UnpackError => error
|
37
50
|
raise UnpackError, error.message
|
38
51
|
rescue IOError => error
|
data/lib/paquito/safe_yaml.rb
CHANGED
@@ -43,31 +43,38 @@ module Paquito
|
|
43
43
|
|
44
44
|
class RestrictedYAMLTree < Psych::Visitors::YAMLTree
|
45
45
|
class DispatchCache
|
46
|
-
def initialize(visitor, cache
|
46
|
+
def initialize(visitor, cache)
|
47
47
|
@visitor = visitor
|
48
48
|
@cache = cache
|
49
|
-
@permitted_classes = permitted_classes
|
50
|
-
|
51
|
-
@permitted_cache = Hash.new do |h, klass|
|
52
|
-
unless @permitted_classes.include?(klass.name)
|
53
|
-
raise UnsupportedType, "Tried to dump unspecified class: #{klass.name.inspect}"
|
54
|
-
end
|
55
|
-
|
56
|
-
h[klass] = true
|
57
|
-
end.compare_by_identity
|
58
49
|
end
|
59
50
|
|
60
51
|
def [](klass)
|
61
|
-
if @
|
62
|
-
@cache[klass]
|
63
|
-
end
|
52
|
+
@cache[klass] if @visitor.permitted_class?(klass)
|
64
53
|
end
|
65
54
|
end
|
66
55
|
|
67
|
-
def initialize(
|
56
|
+
def initialize(*)
|
68
57
|
super
|
69
58
|
@permitted_classes = Set.new(@options[:permitted_classes])
|
70
|
-
@dispatch_cache = DispatchCache.new(self, @dispatch_cache
|
59
|
+
@dispatch_cache = DispatchCache.new(self, @dispatch_cache)
|
60
|
+
@permitted_cache = Hash.new do |h, klass|
|
61
|
+
unless @permitted_classes.include?(klass.name)
|
62
|
+
raise UnsupportedType, "Tried to dump unspecified class: #{klass.name.inspect}"
|
63
|
+
end
|
64
|
+
|
65
|
+
h[klass] = true
|
66
|
+
end.compare_by_identity
|
67
|
+
end
|
68
|
+
ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true)
|
69
|
+
|
70
|
+
def dump_coder(target)
|
71
|
+
return unless permitted_class?(target.class)
|
72
|
+
|
73
|
+
super
|
74
|
+
end
|
75
|
+
|
76
|
+
def permitted_class?(klass)
|
77
|
+
@permitted_cache[klass]
|
71
78
|
end
|
72
79
|
end
|
73
80
|
end
|
data/lib/paquito/typed_struct.rb
CHANGED
data/lib/paquito/types.rb
CHANGED
@@ -37,10 +37,12 @@ module Paquito
|
|
37
37
|
def register(klass, packer: nil, unpacker:)
|
38
38
|
if packer
|
39
39
|
raise ArgumentError, "packer for #{klass} already defined" if packers.key?(klass)
|
40
|
+
|
40
41
|
packers[klass] = packer
|
41
42
|
end
|
42
43
|
|
43
44
|
raise ArgumentError, "unpacker for #{klass} already defined" if unpackers.key?(klass)
|
45
|
+
|
44
46
|
unpackers[klass] = unpacker
|
45
47
|
|
46
48
|
self
|
@@ -72,13 +74,13 @@ module Paquito
|
|
72
74
|
# New types can be added as long as they have unique #code.
|
73
75
|
TYPES = {
|
74
76
|
"Symbol" => {
|
75
|
-
code:
|
76
|
-
packer: :to_s,
|
77
|
+
code: 0,
|
78
|
+
packer: Symbol.method_defined?(:name) ? :name : :to_s,
|
77
79
|
unpacker: :to_sym,
|
78
80
|
optimized_symbols_parsing: true,
|
79
81
|
}.freeze,
|
80
82
|
"Time" => {
|
81
|
-
code:
|
83
|
+
code: 1,
|
82
84
|
packer: ->(value) do
|
83
85
|
rational = value.utc.to_r
|
84
86
|
[rational.numerator, rational.denominator].pack(TIME_FORMAT)
|
@@ -89,7 +91,7 @@ module Paquito
|
|
89
91
|
end,
|
90
92
|
}.freeze,
|
91
93
|
"DateTime" => {
|
92
|
-
code:
|
94
|
+
code: 2,
|
93
95
|
packer: ->(value) do
|
94
96
|
sec = value.sec + value.sec_fraction
|
95
97
|
offset = value.offset
|
@@ -129,7 +131,7 @@ module Paquito
|
|
129
131
|
end,
|
130
132
|
}.freeze,
|
131
133
|
"Date" => {
|
132
|
-
code:
|
134
|
+
code: 3,
|
133
135
|
packer: ->(value) do
|
134
136
|
[value.year, value.month, value.day].pack(DATE_FORMAT)
|
135
137
|
end,
|
@@ -139,28 +141,29 @@ module Paquito
|
|
139
141
|
end,
|
140
142
|
}.freeze,
|
141
143
|
"BigDecimal" => {
|
142
|
-
code:
|
144
|
+
code: 4,
|
143
145
|
packer: :_dump,
|
144
146
|
unpacker: BigDecimal.method(:_load),
|
145
147
|
}.freeze,
|
146
148
|
# Range => { code: 0x05 }, do not recycle that code
|
147
149
|
"ActiveRecord::Base" => {
|
148
|
-
code:
|
150
|
+
code: 6,
|
149
151
|
packer: ->(value) { ActiveRecordPacker.dump(value) },
|
150
152
|
unpacker: ->(value) { ActiveRecordPacker.load(value) },
|
151
153
|
}.freeze,
|
152
154
|
"ActiveSupport::HashWithIndifferentAccess" => {
|
153
|
-
code:
|
155
|
+
code: 7,
|
154
156
|
packer: ->(factory, value) do
|
155
157
|
unless value.instance_of?(ActiveSupport::HashWithIndifferentAccess)
|
156
158
|
raise PackError.new("cannot pack HashWithIndifferentClass subclass", value)
|
157
159
|
end
|
160
|
+
|
158
161
|
factory.dump(value.to_h)
|
159
162
|
end,
|
160
163
|
unpacker: ->(factory, value) { HashWithIndifferentAccess.new(factory.load(value)) },
|
161
164
|
},
|
162
165
|
"ActiveSupport::TimeWithZone" => {
|
163
|
-
code:
|
166
|
+
code: 8,
|
164
167
|
packer: ->(value) do
|
165
168
|
[
|
166
169
|
value.utc.to_i,
|
@@ -176,12 +179,27 @@ module Paquito
|
|
176
179
|
end,
|
177
180
|
},
|
178
181
|
"Set" => {
|
179
|
-
code:
|
182
|
+
code: 9,
|
180
183
|
packer: ->(factory, value) { factory.dump(value.to_a) },
|
181
184
|
unpacker: ->(factory, value) { factory.load(value).to_set },
|
182
185
|
},
|
183
|
-
#
|
184
|
-
|
186
|
+
# Integer => { code: 10 }, reserved for oversized Integer
|
187
|
+
# Object => { code: 127 }, reserved for serializable Object type
|
188
|
+
}
|
189
|
+
begin
|
190
|
+
require "msgpack/bigint"
|
191
|
+
|
192
|
+
TYPES["Integer"] = {
|
193
|
+
code: 10,
|
194
|
+
packer: MessagePack::Bigint.method(:to_msgpack_ext),
|
195
|
+
unpacker: MessagePack::Bigint.method(:from_msgpack_ext),
|
196
|
+
oversized_integer_extension: true,
|
197
|
+
}
|
198
|
+
rescue LoadError
|
199
|
+
# expected on older msgpack
|
200
|
+
end
|
201
|
+
|
202
|
+
TYPES.freeze
|
185
203
|
|
186
204
|
class << self
|
187
205
|
def register(factory, types)
|
@@ -194,15 +212,23 @@ module Paquito
|
|
194
212
|
end
|
195
213
|
|
196
214
|
type_attributes = TYPES.fetch(name)
|
215
|
+
type_attributes = type_attributes.merge(
|
216
|
+
packer: curry_callback(type_attributes.fetch(:packer), factory),
|
217
|
+
unpacker: curry_callback(type_attributes.fetch(:unpacker), factory),
|
218
|
+
)
|
197
219
|
factory.register_type(
|
198
220
|
type_attributes.fetch(:code),
|
199
221
|
type,
|
200
|
-
|
201
|
-
unpacker: curry_callback(type_attributes.fetch(:unpacker), factory),
|
222
|
+
type_attributes
|
202
223
|
)
|
203
224
|
end
|
204
225
|
end
|
205
226
|
|
227
|
+
def recursive?(type)
|
228
|
+
type_attributes = TYPES.fetch(type.name)
|
229
|
+
recursive_callback?(type_attributes[:packer]) || recursive_callback?(type_attributes[:unpacker])
|
230
|
+
end
|
231
|
+
|
206
232
|
def register_serializable_type(factory)
|
207
233
|
factory.register_type(
|
208
234
|
0x7f,
|
@@ -233,9 +259,14 @@ module Paquito
|
|
233
259
|
|
234
260
|
private
|
235
261
|
|
262
|
+
def recursive_callback?(callback)
|
263
|
+
callback.respond_to?(:arity) && callback.arity != 1
|
264
|
+
end
|
265
|
+
|
236
266
|
def curry_callback(callback, factory)
|
237
267
|
return callback.to_proc if callback.is_a?(Symbol)
|
238
268
|
return callback if callback.arity == 1
|
269
|
+
|
239
270
|
callback.curry.call(factory)
|
240
271
|
end
|
241
272
|
end
|
data/lib/paquito/version.rb
CHANGED
data/paquito.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
spec.description = "Framework for defining efficient and extendable serializers"
|
13
13
|
spec.homepage = "https://github.com/Shopify/paquito"
|
14
14
|
spec.license = "MIT"
|
15
|
-
spec.required_ruby_version = ">= 2.
|
15
|
+
spec.required_ruby_version = ">= 2.6.0"
|
16
16
|
|
17
17
|
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
18
18
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paquito
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -39,6 +39,7 @@ files:
|
|
39
39
|
- LICENSE.txt
|
40
40
|
- README.md
|
41
41
|
- Rakefile
|
42
|
+
- benchmark/msgpack-pooling.rb
|
42
43
|
- bin/console
|
43
44
|
- bin/setup
|
44
45
|
- dev.yml
|
@@ -77,7 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
78
|
requirements:
|
78
79
|
- - ">="
|
79
80
|
- !ruby/object:Gem::Version
|
80
|
-
version: 2.
|
81
|
+
version: 2.6.0
|
81
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
83
|
requirements:
|
83
84
|
- - ">="
|