pump 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9047d695a9bb5dbbec84d04fc9a77bebb43c35f8
4
- data.tar.gz: eeed27e8e5f98a30fa22271af1e6182cc3178bcd
3
+ metadata.gz: c4b95096c96dfa59274e8b007a7946f0223e507c
4
+ data.tar.gz: 12e6c47f2239231db115c160575870739141ef95
5
5
  SHA512:
6
- metadata.gz: 6c696f69ee33b842a90e2bd2790a802415497a29aed0d274331bdefc7d54bc5c975b9e6cb6cfd53e161f95a37447777ceefb51c58b1a65df83e64829e755e0ab
7
- data.tar.gz: f020baf37e32686173e0334193fbd555c93966a3b8924f3ecaa0dd0127a3dbc8c484dba40217ba11a7d682b6bdb4cd27a238bff04cd460dab16708e18443223c
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
@@ -1,6 +1,6 @@
1
1
  # Pump
2
2
 
3
- Fast but inflexible XML encoding for ruby objects.
3
+ Fast but inflexible XML and JSON encoding for ruby objects.
4
4
 
5
5
  ## Quick benchmark
6
6
 
data/benchmarks/encode.rb CHANGED
@@ -4,17 +4,26 @@ require 'rubygems'
4
4
  require 'benchmark'
5
5
 
6
6
  require 'pump'
7
- require 'ox' rescue nil
8
- require 'active_model' rescue nil
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#serialize") {
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
  }
@@ -1,6 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gem "activemodel", "3.2.13"
4
+ gem "oj"
4
5
 
5
6
  gem 'rspec', '>= 2.4.0'
6
7
  gem 'rake'
@@ -1,6 +1,7 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gem "activemodel", "4.0"
4
+ gem "oj"
4
5
 
5
6
  gem 'rspec', '>= 2.4.0'
6
7
  gem 'rake'
data/lib/pump.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "pump/version"
2
2
  require "pump/xml"
3
+ require "pump/json"
3
4
  require "pump/object"
4
5
  require "pump/array"
5
6
 
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
@@ -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
- self.to_xml(options)
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
- pumps.add(set, :xml, Pump::Xml.new(name, options, &block))
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
@@ -1,3 +1,3 @@
1
1
  module Pump
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end