class Protocol::HTTP::Response

~~~
Protocol::HTTP::Response[200, {“content-type” => “text/html”}, [“Hello, World!”]]
# Short form:
Protocol::HTTP::Response.new(“http/1.1”, 200, Protocol::HTTP::Headers[[“content-type”, “text/html”]], Protocol::HTTP::Body::Buffered.wrap(“Hello, World!”))
# Long form:
require ‘protocol/http’
~~~ ruby
Represents an HTTP response which can be used both server and client-side.

def self.[](status, _headers = nil, _body = nil, headers: _headers, body: _body, protocol: nil)

@parameter body [String | Array(String) | Body::Readable] The body, e.g. `"Hello, World!"`, etc. See {Body::Buffered.wrap} for more information about .
@parameter headers [Hash] The headers, e.g. `{"content-type" => "text/html"}`, etc.
@parameter status [Integer] The HTTP status code, e.g. `200`, `404`, etc.

~~~
Response[200, {"content-type" => "text/html"}, ["Hello, World!"]]
~~~ ruby

A short-cut method which exposes the main response variables that you'd typically care about. It follows the same order as the `Rack` response tuple, but also includes the protocol.
def self.[](status, _headers = nil, _body = nil, headers: _headers, body: _body, protocol: nil)
	body = Body::Buffered.wrap(body)
	headers = Headers[headers]
	
	self.new(nil, status, headers, body, protocol)
end

def self.for_exception(exception)

@parameter exception [Exception] The exception to generate the response for.

Create a response for the given exception.
def self.for_exception(exception)
	Response[500, Headers["content-type" => "text/plain"], ["#{exception.class}: #{exception.message}"]]
end

def as_json(...)

@returns [Hash] The response as a hash.

Convert the response to a hash suitable for serialization.
def as_json(...)
	{
		version: @version,
		status: @status,
		headers: @headers&.as_json,
		body: @body&.as_json,
		protocol: @protocol
	}
end

def bad_request?

Whether the status is 400 (bad request).
def bad_request?
	@status == 400
end

def continue?

Whether the status is 100 (continue).
def continue?
	@status == 100
end

def failure?

Whether the status is considered a failure.
def failure?
	@status and @status >= 400 && @status < 600
end

def final?

Whether the status is considered final. Note that 101 is considered final.
def final?
	# 101 is effectively a final status.
	@status and @status >= 200 || @status == 101
end

def hijack?

Whether the response is considered a hijack: the connection has been taken over by the application and the server should not send any more data.
def hijack?
	false
end

def informational?

Whether the status is considered informational.
def informational?
	@status and @status >= 100 && @status < 200
end

def initialize(version = nil, status = 200, headers = Headers.new, body = nil, protocol = nil)

@parameter protocol [String | Array(String)] The protocol, e.g. `"websocket"`, etc.
@parameter body [Body::Readable] The body, e.g. `"Hello, World!"`, etc.
@parameter headers [Hash] The headers, e.g. `{"content-type" => "text/html"}`, etc.
@parameter status [Integer] The HTTP status code, e.g. `200`, `404`, etc.
@parameter version [String | Nil] The HTTP version, e.g. `"HTTP/1.1"`. If `nil`, the version may be provided by the server sending the response.

Create a new response.
def initialize(version = nil, status = 200, headers = Headers.new, body = nil, protocol = nil)
	@version = version
	@status = status
	@headers = headers
	@body = body
	@protocol = protocol
end

def internal_server_error?

Whether the status is 500 (internal server error).
def internal_server_error?
	@status == 500
end

def not_modified?

Whether the status is 304 (not modified).
def not_modified?
	@status == 304
end

def ok?

Whether the status is 200 (ok).
def ok?
	@status == 200
end

def partial?

Whether the status is 206 (partial content).
def partial?
	@status == 206
end

def peer

@returns [Peer | Nil] The peer (address) associated with the response.

A response that is generated by a client, may choose to include the peer (address) associated with the response. It should be implemented by a sub-class.
def peer
	nil
end

def preserve_method?

Whether the status is 307 (temporary redirect) and should preserve the method of the request when following the redirect.
def preserve_method?
	@status == 307 || @status == 308
end

def redirection?

Whether the status is considered a redirection.
def redirection?
	@status and @status >= 300 && @status < 400
end

def success?

Whether the status is considered successful.
def success?
	@status and @status >= 200 && @status < 300
end

def to_ary

@returns [Array] The response as an array, e.g. `[status, headers, body]`.

Implicit conversion to an array.
def to_ary
	return @status, @headers, @body
end

def to_json(...)

@returns [String] The response as JSON.

Convert the response to JSON.
def to_json(...)
	as_json.to_json(...)
end

def to_s

@returns [String] The response as a string.

Summarise the response as a string.
def to_s
	"#{@status} #{@version}"
end