faraday-xml 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d4bf34c7cdf9c459325cce7cc6c4571057eafa9d9d0f3937badf593a7edf4e0
4
- data.tar.gz: 905237976614eba95b0a5ff2a5089c537ecc2d6f27c18e23a622e81d30ab7dba
3
+ metadata.gz: fd31db052ce943d7b8f60e8396449da83c134b70f3fe59f52e105edf1105f20d
4
+ data.tar.gz: 80348c82aa221ff79dbb488bf11b7df6adecbb877887165899a6d057197bc12d
5
5
  SHA512:
6
- metadata.gz: a15dc8568124039c2297460033ab55447197358977523a2245d1e1470f44d0ce1f9602ff0998c8cb3f63a77c64bebf70ad3b20d5c8f956b0ffb32e270d175e15
7
- data.tar.gz: 5805e36c1f2418ad1428eae2c1129feb54734fa321b0f5cbcc2e8cd34c2327f9a4189ec7888e6de3b031bbac353023f7749525a5772e5f265f3ed94d71d7f555
6
+ metadata.gz: 33acfe362ff340f1e39f40a1610c77b98ccd89d7b0e107625fd2d7fc4ef08ed52c34166a3903cdb64514f5861a7420d181495355572d772be0b697870fb5986f
7
+ data.tar.gz: 347b1ab466889029e44fb4cba75d5845bcf959544154d4fc8cb653a2988397f8a7edb19e4e7115d77594e83962ac07a017c0ab15f8fba76339fc3124b6676b23
data/CHANGELOG.md CHANGED
@@ -1,7 +1,11 @@
1
1
  # Changelog
2
2
 
3
- ## [Unreleased](https://github.com/gemhome/faraday-xml/compare/v0.1.0...main)
3
+ ## [Unreleased](https://github.com/gemhome/faraday-xml/compare/v0.2.0...main)
4
+
5
+ ## [0.2.0](https://github.com/gemhome/faraday-xml/compare/v0.1.0...v0.2.0)
6
+
7
+ * feat: simple Hash -> XML request encoder
4
8
 
5
9
  ## [0.1.0](https://github.com/gemhome/faraday-xml/blob/v0.1.0) (2023-01-12)
6
10
 
7
- * Initial release.
11
+ * feat: Initial release.
data/README.md CHANGED
@@ -37,7 +37,8 @@ conn = Faraday.new do |builder|
37
37
  "Accept" => "application/xml",
38
38
  "Content-Type" => "application/xml;charset=UTF-8",
39
39
  )
40
-
40
+ # or builder.use Faraday::XML::Request
41
+ builder.request :xml # encode Hash as XML
41
42
  # or builder.use Faraday::XML::Response
42
43
  builder.response :xml # decode response bodies from XML
43
44
  end
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ module XML
5
+ # Request middleware that encodes the body as XML.
6
+ #
7
+ # Processes only requests with matching Content-type or those without a type.
8
+ # If a request doesn't have a type but has a body, it sets the Content-type
9
+ # to XML MIME-type.
10
+ #
11
+ # Doesn't try to encode bodies that already are in string form.
12
+ class Request < Middleware # rubocop:disable Metrics/ClassLength
13
+ MIME_TYPE = 'application/xml'
14
+ MIME_TYPE_REGEX = %r{^application/(vnd\..+\+)?xml$}.freeze
15
+
16
+ def initialize(app = nil, options = {})
17
+ super(app)
18
+ @encoder_options = options.fetch(:encoder_options, {})
19
+ end
20
+
21
+ def on_request(env)
22
+ match_content_type(env) do |data|
23
+ env[:body] = encode(data)
24
+ end
25
+ end
26
+
27
+ def encoder
28
+ @encoder ||= nil
29
+ if @encoder.nil?
30
+ @encoder = set_encoder
31
+ @encoder && test_encoder
32
+ end
33
+ @encoder or raise 'Missing dependencies Builder'
34
+ end
35
+
36
+ private
37
+
38
+ def encode(data)
39
+ encoder.call(data)
40
+ end
41
+
42
+ def test_encoder
43
+ encode({ success: true })
44
+ end
45
+
46
+ def set_encoder
47
+ @encoder ||= # rubocop:disable Naming/MemoizedInstanceVariableName
48
+ begin
49
+ require 'builder'
50
+ lambda do |parameter_hash|
51
+ parameters_as_xml(parameter_hash)
52
+ end
53
+ rescue LoadError # rubocop:disable Lint/SuppressedException
54
+ end
55
+ end
56
+
57
+ def match_content_type(env)
58
+ return unless process_request?(env)
59
+
60
+ env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
61
+ yield env[:body] unless env[:body].respond_to?(:to_str)
62
+ end
63
+
64
+ def process_request?(env)
65
+ type = request_type(env)
66
+ body?(env) && (type.empty? || type.match?(MIME_TYPE_REGEX))
67
+ end
68
+
69
+ def body?(env)
70
+ (body = env[:body]) && !(body.respond_to?(:to_str) && body.empty?)
71
+ end
72
+
73
+ def request_type(env)
74
+ type = env[:request_headers][CONTENT_TYPE].to_s
75
+ type = type.split(';', 2).first if type.index(';')
76
+ type
77
+ end
78
+
79
+ def parameters_as_xml(parameter_hash) # rubocop:disable Metrics/MethodLength
80
+ xml_markup = build_xml_markup(skip_instruct: true)
81
+ parameter_hash.each_pair do |key, value|
82
+ key = key.to_s
83
+ if _parameter_as_xml?(value)
84
+ xml_markup.tag!(key) do
85
+ xml = _parameter_as_xml(value)
86
+ xml_markup << xml
87
+ end
88
+ else
89
+ xml_markup.tag!(key, _parameter_as_xml(value))
90
+ end
91
+ end
92
+ xml_markup.target!
93
+ end
94
+
95
+ def _parameter_as_xml?(value)
96
+ case value
97
+ when Hash, Array then true
98
+ else false
99
+ end
100
+ end
101
+
102
+ def _parameter_as_xml(value)
103
+ case value
104
+ when Hash
105
+ parameters_as_xml(value) # recursive case
106
+ when Array
107
+ _parameter_as_list_xml(value) # recursive case
108
+ else
109
+ value.to_s.encode(xml: :text) # end case
110
+ end
111
+ end
112
+
113
+ def _parameter_as_list_xml(array_of_hashes)
114
+ xml_markup = build_xml_markup(skip_instruct: true)
115
+ array_of_hashes.each do |value|
116
+ xml_markup << parameters_as_xml(value) # recursive case
117
+ end
118
+ xml_markup.target!
119
+ end
120
+
121
+ def build_xml_markup(**options)
122
+ # https://github.com/rails/rails/blob/86fd8d0143b1a0578b359f4b86fea94c718139ae/activesupport/lib/active_support/builder.rb
123
+ # https://github.com/rails/rails/blob/86fd8d0143b1a0578b359f4b86fea94c718139ae/activesupport/lib/active_support/core_ext/hash/conversions.rb
124
+ require 'builder'
125
+ options.merge!(@encoder_options)
126
+ options[:indent] = 2 unless options.key?(:indent)
127
+ xml_markup = ::Builder::XmlMarkup.new(**options)
128
+ if !options.delete(:skip_instruct) # rubocop:disable Style/NegatedIf
129
+ xml_markup.instruct! :xml, version: '1.0', encoding: 'UTF-8'
130
+ end
131
+ xml_markup
132
+ end
133
+ end
134
+ end
135
+ end
@@ -10,7 +10,6 @@ module Faraday
10
10
  @content_types = Array(options.fetch(:content_type, /\bxml$/))
11
11
  @preserve_raw = options.fetch(:preserve_raw, false)
12
12
  end
13
- ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true)
14
13
 
15
14
  # @param env [Faraday::Env] the environment of the response being processed.
16
15
  def on_complete(env)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Faraday
4
4
  module XML
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
  end
7
7
  end
data/lib/faraday/xml.rb CHANGED
@@ -1,11 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'xml/request'
3
4
  require_relative 'xml/response'
4
5
  require_relative 'xml/version'
5
6
 
6
7
  module Faraday
7
8
  # The Faraday::XML middleware main module
8
9
  module XML
10
+ # Load middleware with
11
+ # conn.use Faraday::XML::Request
12
+ # or
13
+ # conn.request :xml
14
+ Faraday::Request.register_middleware(xml: Faraday::XML::Request)
9
15
  # Load middleware with
10
16
  # conn.use Faraday::XML::Response
11
17
  # or
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday-xml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Fleischer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-13 00:00:00.000000000 Z
11
+ date: 2023-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -155,6 +155,7 @@ files:
155
155
  - LICENSE.md
156
156
  - README.md
157
157
  - lib/faraday/xml.rb
158
+ - lib/faraday/xml/request.rb
158
159
  - lib/faraday/xml/response.rb
159
160
  - lib/faraday/xml/version.rb
160
161
  homepage: https://github.com/gemhome/faraday-xml
@@ -162,8 +163,8 @@ licenses:
162
163
  - MIT
163
164
  metadata:
164
165
  bug_tracker_uri: https://github.com/gemhome/faraday-xml/issues
165
- changelog_uri: https://github.com/gemhome/faraday-xml/blob/v0.1.0/CHANGELOG.md
166
- documentation_uri: http://www.rubydoc.info/gems/faraday-xml/0.1.0
166
+ changelog_uri: https://github.com/gemhome/faraday-xml/blob/v0.2.0/CHANGELOG.md
167
+ documentation_uri: http://www.rubydoc.info/gems/faraday-xml/0.2.0
167
168
  homepage_uri: https://github.com/gemhome/faraday-xml
168
169
  rubygems_mfa_required: 'true'
169
170
  source_code_uri: https://github.com/gemhome/faraday-xml