Class: Petail::Payload

Inherits:
Struct
  • Object
show all
Defined in:
lib/petail/payload.rb

Overview

Models the problem details response payload.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePayload

Returns a new instance of Payload.



43
44
45
46
47
48
49
# File 'lib/petail/payload.rb', line 43

def initialize(**)
  super
  self[:type] ||= "about:blank"
  self[:title] ||= Rack::Utils::HTTP_STATUS_CODES[status]
  self[:extensions] ||= {}
  freeze
end

Instance Attribute Details

#extensionsObject

Returns the value of attribute extensions

Returns:

  • (Object)

    the current value of extensions



11
12
13
# File 'lib/petail/payload.rb', line 11

def extensions
  @extensions
end

Class Method Details

.for(**attributes) ⇒ Object



12
13
14
15
16
17
# File 'lib/petail/payload.rb', line 12

def self.for(**attributes)
  status = attributes.delete(:status).then { Rack::Utils.status_code it if it }
  title = attributes.delete(:title).then { it || Rack::Utils::HTTP_STATUS_CODES[status] }

  new title:, status:, **attributes
end

.from_json(body) ⇒ Object



19
20
21
22
23
24
# File 'lib/petail/payload.rb', line 19

def self.from_json body
  attributes = JSON body, symbolize_names: true
  extensions = attributes.reject { |key| PRIMARY_KEYS.include? key }

  self.for(**attributes.slice(*PRIMARY_KEYS), extensions:)
end

.from_xml(body, deserializer: XML::Deserializer) ⇒ Object

:reek:TooManyStatements



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/petail/payload.rb', line 27

def self.from_xml body, deserializer: XML::Deserializer
  elements = REXML::Document.new(body).root.elements

  attributes = elements.each_with_object({extensions: {}}) do |element, collection|
    name = element.name.to_sym
    text = element.text

    case name
      when *PRIMARY_KEYS then collection[name] = text
      else collection[:extensions].merge! deserializer.call(element)
    end
  end

  self.for(**attributes)
end

Instance Method Details

#add_extension(name, value) ⇒ Object



51
52
53
54
# File 'lib/petail/payload.rb', line 51

def add_extension name, value
  self[:extensions][name] = value
  self
end

#extension?(name) ⇒ Boolean

Returns:

  • (Boolean)


56
# File 'lib/petail/payload.rb', line 56

def extension?(name) = extensions.key? name

#to_hObject



58
# File 'lib/petail/payload.rb', line 58

def to_h = {type:, title:, status:, detail:, instance:, **extensions}.compact

#to_jsonObject



60
# File 'lib/petail/payload.rb', line 60

def to_json(*) = to_h.to_json(*)

#to_xml(serializer: XML::Serializer, **options) ⇒ Object

:reek:TooManyStatements :reek:FeatureEnvy



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/petail/payload.rb', line 64

def to_xml(serializer: XML::Serializer, **options)
  document = REXML::Document.new
  document.add REXML::XMLDecl.new("1.0", "UTF-8")

  problem = REXML::Element.new("problem").add_namespace("urn:ietf:rfc:7807")
  document.add problem

  to_h.each { |name, value| serializer.call name, value, problem }

  "".dup.tap { document.write(**options, output: it) }
end