pump 0.5.1 → 0.6.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/CHANGES.md +8 -1
- data/README.md +1 -1
- data/benchmarks/encode.rb +40 -3
- data/gemfiles/activesupport-3-2 +1 -0
- data/gemfiles/activesupport-4 +1 -0
- data/lib/pump.rb +1 -0
- data/lib/pump/array.rb +7 -1
- data/lib/pump/dsl.rb +57 -0
- data/lib/pump/encoder.rb +92 -0
- data/lib/pump/json.rb +97 -0
- data/lib/pump/object.rb +19 -3
- data/lib/pump/version.rb +1 -1
- data/lib/pump/xml.rb +14 -69
- data/pump.gemspec +3 -2
- data/spec/pump/array_spec.rb +34 -2
- data/spec/pump/{xml/dsl_spec.rb → dsl_spec.rb} +22 -22
- data/spec/pump/encoder_spec.rb +97 -0
- data/spec/pump/json_spec.rb +218 -0
- data/spec/pump/object_spec.rb +82 -3
- data/spec/pump/xml_spec.rb +0 -19
- metadata +27 -7
- data/lib/pump/xml/dsl.rb +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4b95096c96dfa59274e8b007a7946f0223e507c
|
4
|
+
data.tar.gz: 12e6c47f2239231db115c160575870739141ef95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9725fb7b0bb3152bae3321623744f15e280bfc4edae242836702b3971bd69039007f7c54bc8b1e7a49f49b0d440f7d66db989642b64ad2b8e09858ff1d32e210
|
7
|
+
data.tar.gz: 360c20c887a7c50232df40b77805e86a26d8a8c399695fba4e360121eb721841768918f4738ac6fe957b75bac8d0c161b19eebdee27ebdd95707d45d7ccb758b
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
1
|
### dev
|
2
2
|
|
3
|
-
[full changelog](http://github.com/yolk/pump/compare/v0.0.1...master)
|
3
|
+
[full changelog](http://github.com/yolk/pump/compare/v0.0.1...master)
|
4
|
+
|
5
|
+
### 0.6.0 / 2013-07-24
|
6
|
+
|
7
|
+
[full changelog](http://github.com/yolk/valvat/compare/v0.5.1...v0.6.0)
|
8
|
+
|
9
|
+
* Added JSON serialization
|
10
|
+
* Added simple inheritance for encoders
|
data/README.md
CHANGED
data/benchmarks/encode.rb
CHANGED
@@ -4,17 +4,26 @@ require 'rubygems'
|
|
4
4
|
require 'benchmark'
|
5
5
|
|
6
6
|
require 'pump'
|
7
|
-
require 'ox'
|
8
|
-
require '
|
7
|
+
require 'ox'
|
8
|
+
require 'oj'
|
9
|
+
require 'yajl'
|
10
|
+
require 'active_model'
|
9
11
|
|
10
12
|
class Person < Struct.new(:name, :age, :created_at)
|
11
13
|
include ActiveModel::Serializers::Xml if defined?(ActiveModel)
|
14
|
+
include ActiveModel::Serializers::JSON if defined?(ActiveModel)
|
12
15
|
|
13
16
|
def attributes
|
14
17
|
{'name' => name, 'age' => age, 'created_at' => created_at}
|
15
18
|
end
|
16
19
|
end
|
17
20
|
|
21
|
+
pump_json = Pump::Json.new('person', [
|
22
|
+
{:age => :age, :attributes => {:type => 'integer'}},
|
23
|
+
{:"created-at" => :created_at, :typecast => :xmlschema, :attributes => {:type => 'datetime'}, :never_nil => true},
|
24
|
+
{:name => :name}
|
25
|
+
])
|
26
|
+
|
18
27
|
# Not optimized pump
|
19
28
|
pump = Pump::Xml.new('person', [
|
20
29
|
{:age => :age, :attributes => {:type => 'integer'}},
|
@@ -77,6 +86,12 @@ puts "Starting benchmark serializing array with #{array.size} entries #{times} t
|
|
77
86
|
|
78
87
|
Benchmark.bmbm { |x|
|
79
88
|
|
89
|
+
x.report("Pump::Json#encode") {
|
90
|
+
times.times {
|
91
|
+
pump_json.encode(array)
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
80
95
|
x.report("Pump::Xml#encode") {
|
81
96
|
times.times {
|
82
97
|
pump.encode(array)
|
@@ -97,11 +112,33 @@ Benchmark.bmbm { |x|
|
|
97
112
|
}
|
98
113
|
end
|
99
114
|
|
115
|
+
if defined?(Oj)
|
116
|
+
x.report("Oj") {
|
117
|
+
times.times {
|
118
|
+
Oj.dump(array.map(&:attributes), :mode => :compat)
|
119
|
+
}
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
if defined?(Yajl)
|
124
|
+
x.report("Yajl") {
|
125
|
+
times.times {
|
126
|
+
Yajl::Encoder.encode(array.map(&:attributes))
|
127
|
+
}
|
128
|
+
}
|
129
|
+
end
|
130
|
+
|
100
131
|
if defined?(ActiveModel)
|
101
|
-
x.report("ActiveModel#
|
132
|
+
x.report("ActiveModel#to_xml") {
|
102
133
|
times.times {
|
103
134
|
array.to_xml
|
104
135
|
}
|
105
136
|
}
|
137
|
+
|
138
|
+
x.report("ActiveModel#to_json") {
|
139
|
+
times.times {
|
140
|
+
array.to_json
|
141
|
+
}
|
142
|
+
}
|
106
143
|
end
|
107
144
|
}
|
data/gemfiles/activesupport-3-2
CHANGED
data/gemfiles/activesupport-4
CHANGED
data/lib/pump.rb
CHANGED
data/lib/pump/array.rb
CHANGED
@@ -3,7 +3,13 @@ module Pump
|
|
3
3
|
def pump_to_xml(options={})
|
4
4
|
encoder = get_pump_encoder(options[:set], :xml)
|
5
5
|
return to_xml(options) unless encoder
|
6
|
-
encoder.encode(self)
|
6
|
+
encoder.encode(self, options)
|
7
|
+
end
|
8
|
+
|
9
|
+
def pump_to_json(options={})
|
10
|
+
encoder = get_pump_encoder(options[:set], :json)
|
11
|
+
return to_json(options) unless encoder
|
12
|
+
encoder.encode(self, options)
|
7
13
|
end
|
8
14
|
|
9
15
|
private
|
data/lib/pump/dsl.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Pump
|
2
|
+
class Dsl
|
3
|
+
def initialize(&blk)
|
4
|
+
raise ArgumentError unless block_given?
|
5
|
+
instance_eval(&blk)
|
6
|
+
end
|
7
|
+
|
8
|
+
def config
|
9
|
+
@config ||= []
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def tag(name, options={}, &blk)
|
15
|
+
method = if block_given?
|
16
|
+
self.class.new(&blk).config
|
17
|
+
else
|
18
|
+
options.delete(:from) || (name.to_s =~ /-/ ? name.to_s.gsub('-', '_').to_sym : name)
|
19
|
+
end
|
20
|
+
config << ({ name => method }).merge(options)
|
21
|
+
end
|
22
|
+
alias_method :string, :tag
|
23
|
+
|
24
|
+
def integer(name, options={})
|
25
|
+
with_type('integer', name, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def float(name, options={})
|
29
|
+
with_type('float', name, options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def boolean(name, options={})
|
33
|
+
with_type('boolean', name, options)
|
34
|
+
end
|
35
|
+
|
36
|
+
def date(name, options={})
|
37
|
+
with_type('date', name, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
def datetime(name, options={})
|
41
|
+
options[:typecast] = :xmlschema unless options.has_key?(:typecast)
|
42
|
+
with_type('datetime', name, options)
|
43
|
+
end
|
44
|
+
alias_method :time, :datetime
|
45
|
+
|
46
|
+
def with_type(type, name, options)
|
47
|
+
(options[:attributes] ||= {}).merge!({:type => type})
|
48
|
+
options[:xmlsafe] = true unless options.has_key?(:xmlsafe)
|
49
|
+
tag(name, options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def array(name, options={}, &blk)
|
53
|
+
options[:array] = self.class.new(&blk).config
|
54
|
+
tag(name, options)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/pump/encoder.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require "pump/dsl"
|
2
|
+
|
3
|
+
module Pump
|
4
|
+
class Encoder
|
5
|
+
attr_reader :root_name, :encoder_config, :encoder_options, :base
|
6
|
+
|
7
|
+
# Creates a new XML-encoder with a root tag named after +root_name+.
|
8
|
+
#
|
9
|
+
# @example Create a simple encoder for a person with a name attribute:
|
10
|
+
# Pump::Xml.new :person do
|
11
|
+
# tag :name
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# @example Create the same without usage of the DSL:
|
15
|
+
# Pump::Xml.new :person, [{:name => :name}]
|
16
|
+
#
|
17
|
+
# @example Create the same but without the xml instruct
|
18
|
+
# Pump::Xml.new :person, :instruct => false do
|
19
|
+
# tag :name
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# @example The same again without DSL:
|
23
|
+
#
|
24
|
+
# Pump::Xml.new :person, [{:name => :name}], :instruct => false
|
25
|
+
#
|
26
|
+
# @param [String, Symbol] root_name the name of the used root tag
|
27
|
+
# @param [Array<Hash>] encoder_config optional config for all tags
|
28
|
+
# @param [Hash] encoder_options optional encoder_options for the whole encoder
|
29
|
+
# @yield an optional block to create the encoder with the Pump::Dsl
|
30
|
+
#
|
31
|
+
# @return [self]
|
32
|
+
def initialize(root_name, encoder_config=nil, encoder_options={}, &blk)
|
33
|
+
if encoder_config.is_a?(Array)
|
34
|
+
@encoder_config = encoder_config
|
35
|
+
@encoder_options = encoder_options || {}
|
36
|
+
else
|
37
|
+
raise ArgumentError unless block_given?
|
38
|
+
@encoder_options = encoder_config || {}
|
39
|
+
@encoder_config = Pump::Dsl.new(&blk).config
|
40
|
+
end
|
41
|
+
@root_name = root_name
|
42
|
+
merge_base
|
43
|
+
|
44
|
+
compile
|
45
|
+
end
|
46
|
+
|
47
|
+
# Encode a object or an array of objects to an XML-string.
|
48
|
+
#
|
49
|
+
# @param [Object, Array<Object>] object object or an array of objects to
|
50
|
+
# encode to XML. The only requirement: The given objects must respond
|
51
|
+
# to all methods configured during initalization of the Pump::Xml instance.
|
52
|
+
#
|
53
|
+
# @return [String]
|
54
|
+
def encode(object, options={})
|
55
|
+
object.is_a?(Array) ? encode_array(object, options) : encode_single(object, options)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def compile
|
61
|
+
compile_string && instance_eval(compile_string)
|
62
|
+
end
|
63
|
+
|
64
|
+
def compile_string;end
|
65
|
+
|
66
|
+
def merge_base
|
67
|
+
return unless @encoder_options[:base]
|
68
|
+
@base = @encoder_options.delete(:base)
|
69
|
+
|
70
|
+
merge_base_config
|
71
|
+
merge_base_options
|
72
|
+
end
|
73
|
+
|
74
|
+
def merge_base_config
|
75
|
+
original_encoder_config = @encoder_config
|
76
|
+
@encoder_config = base.encoder_config.dup
|
77
|
+
original_encoder_config.each do |it|
|
78
|
+
key = it.keys.first
|
79
|
+
index = @encoder_config.index{|config| config.keys.first == key}
|
80
|
+
if index
|
81
|
+
@encoder_config[index] = it
|
82
|
+
else
|
83
|
+
@encoder_config.push(it)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def merge_base_options
|
89
|
+
encoder_options.merge!(base.encoder_options) { |key, v1, v2| v1 }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/pump/json.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
require "pump/encoder"
|
2
|
+
require "oj"
|
3
|
+
|
4
|
+
module Pump
|
5
|
+
class Json < Encoder
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
def compile_string
|
10
|
+
<<-EOV
|
11
|
+
def encode_single(object, options)
|
12
|
+
json = {}
|
13
|
+
#{build_string(encoder_config)}
|
14
|
+
unless options[:exclude_root_in_json]
|
15
|
+
json = { :'#{format_name(root_name)}' => json }
|
16
|
+
end
|
17
|
+
Oj.dump(json, :mode => :compat)
|
18
|
+
end
|
19
|
+
|
20
|
+
def encode_array(objects, options)
|
21
|
+
Oj.dump(if options[:exclude_root_in_json]
|
22
|
+
objects.map do |object|
|
23
|
+
json = {}
|
24
|
+
#{build_string(encoder_config)}
|
25
|
+
json
|
26
|
+
end
|
27
|
+
else
|
28
|
+
objects.map do |object|
|
29
|
+
json = {}
|
30
|
+
#{build_string(encoder_config)}
|
31
|
+
{ :'#{format_name(root_name)}' => json }
|
32
|
+
end
|
33
|
+
end, :mode => :compat)
|
34
|
+
end
|
35
|
+
EOV
|
36
|
+
end
|
37
|
+
|
38
|
+
def build_string(config, variable='json')
|
39
|
+
config.inject("") do |str, config|
|
40
|
+
build_key_value_pair(str, config, variable)
|
41
|
+
str
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def build_key_value_pair(str, config, variable='json')
|
46
|
+
name, method_name = config.keys.first, config.values.first
|
47
|
+
if method_name.is_a?(Array) && !config.has_key?(:static_value)
|
48
|
+
build_hash(str, name, method_name, config, variable)
|
49
|
+
elsif config[:array]
|
50
|
+
build_array(str, name, method_name, config, variable)
|
51
|
+
else
|
52
|
+
build_simple(str, name, method_name, config, variable)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_hash(str, name, method_name, config, variable)
|
57
|
+
str << "#{build_condition(config)}\n"
|
58
|
+
str << "#{variable}[:'#{format_name(name)}'] = {}\n"
|
59
|
+
str << build_string(method_name, "#{variable}[:'#{format_name(name)}']")
|
60
|
+
str << "end\n" if build_condition(config)
|
61
|
+
end
|
62
|
+
|
63
|
+
def build_array(str, name, method_name, config, variable)
|
64
|
+
str << "#{build_condition(config)}\n"
|
65
|
+
str << "#{variable}[:'#{format_name(name)}'] = []\n"
|
66
|
+
unless config.has_key?(:static_value)
|
67
|
+
str << "object.#{method_name}.each do |object| "
|
68
|
+
str << "#{variable}[:'#{format_name(name)}'] << {}\n"
|
69
|
+
str << build_string(config[:array], "#{variable}[:'#{format_name(name)}'][-1]")
|
70
|
+
str << "end\n"
|
71
|
+
end
|
72
|
+
str << "end\n" if build_condition(config)
|
73
|
+
end
|
74
|
+
|
75
|
+
def build_simple(str, name, method_name, config, variable)
|
76
|
+
str << "#{variable}[:'#{format_name(name)}']=#{build_value(method_name, config)}#{build_condition(config)}\n"
|
77
|
+
end
|
78
|
+
|
79
|
+
def build_value(method_name, config)
|
80
|
+
return config[:static_value].inspect if config.has_key?(:static_value)
|
81
|
+
"object.#{method_name}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def build_condition(config)
|
85
|
+
if config[:if]
|
86
|
+
" if object.#{config[:if]}"
|
87
|
+
elsif config[:unless]
|
88
|
+
" unless object.#{config[:unless]}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def format_name(name)
|
93
|
+
return name if encoder_options[:underscore] == false
|
94
|
+
name.to_s.underscore
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/lib/pump/object.rb
CHANGED
@@ -9,9 +9,18 @@ module Pump
|
|
9
9
|
def pump_to_xml(options={})
|
10
10
|
encoder = self.class.pumps.get(options[:set], :xml)
|
11
11
|
if encoder
|
12
|
-
encoder.encode(self)
|
12
|
+
encoder.encode(self, options)
|
13
13
|
else
|
14
|
-
|
14
|
+
to_xml(options)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def pump_to_json(options={})
|
19
|
+
encoder = self.class.pumps.get(options[:set], :json)
|
20
|
+
if encoder
|
21
|
+
encoder.encode(self, options)
|
22
|
+
else
|
23
|
+
to_json(options)
|
15
24
|
end
|
16
25
|
end
|
17
26
|
|
@@ -21,7 +30,14 @@ module Pump
|
|
21
30
|
end
|
22
31
|
|
23
32
|
def add_pump(name, set=nil, options={}, &block)
|
24
|
-
|
33
|
+
if options[:base]
|
34
|
+
xml_options = options.dup.merge({:base => pumps.get(options[:base], :xml)})
|
35
|
+
json_options = options.dup.merge({:base => pumps.get(options[:base], :json)})
|
36
|
+
else
|
37
|
+
xml_options, json_options = options, options
|
38
|
+
end
|
39
|
+
pumps.add(set, :xml, Pump::Xml.new(name, xml_options, &block))
|
40
|
+
pumps.add(set, :json, Pump::Json.new(name, json_options, &block))
|
25
41
|
end
|
26
42
|
end
|
27
43
|
end
|
data/lib/pump/version.rb
CHANGED