File: json.rb

package info (click to toggle)
ruby-httpx 1.7.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,816 kB
  • sloc: ruby: 12,209; makefile: 4
file content (71 lines) | stat: -rw-r--r-- 1,794 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# frozen_string_literal: true

require "forwardable"

module HTTPX::Transcoder
  module JSON
    module_function

    JSON_REGEX = %r{
      \b
      application/
      # optional vendor specific type
      (?:
        # token as per https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
        [!#$%&'*+\-.^_`|~0-9a-z]+
        # literal plus sign
        \+
      )?
      json
      \b
    }ix.freeze

    class Encoder
      extend Forwardable

      def_delegator :@raw, :to_s

      def_delegator :@raw, :bytesize

      def_delegator :@raw, :==

      def initialize(json)
        @raw = JSON.json_dump(json)
        @charset = @raw.encoding.name.downcase
      end

      def content_type
        "application/json; charset=#{@charset}"
      end
    end

    def encode(json)
      Encoder.new(json)
    end

    def decode(response)
      content_type = response.content_type.mime_type

      raise HTTPX::Error, "invalid json mime type (#{content_type})" unless JSON_REGEX.match?(content_type)

      method(:json_load)
    end

    # rubocop:disable Style/SingleLineMethods
    if defined?(MultiJson)
      def json_load(*args); MultiJson.load(*args); end
      def json_dump(*args); MultiJson.dump(*args); end
    elsif defined?(Oj)
      def json_load(response, *args); Oj.load(response.to_s, *args); end
      def json_dump(obj, options = {}); Oj.dump(obj, { mode: :compat }.merge(options)); end
    elsif defined?(Yajl)
      def json_load(response, *args); Yajl::Parser.new(*args).parse(response.to_s); end
      def json_dump(*args); Yajl::Encoder.encode(*args); end
    else
      require "json"
      def json_load(*args); ::JSON.parse(*args); end
      def json_dump(*args); ::JSON.generate(*args); end
    end
    # rubocop:enable Style/SingleLineMethods
  end
end