module Protocol::HTTP::Body::Reader

def body?

@returns [Boolean] whether there is a body.

Whether there is a body?
def body?
	@body and !@body.empty?
end

def buffered!

@returns [Reader] itself.

Buffer the entire request/response body.
def buffered!
	if @body
		@body = @body.finish
	end
	
	# TODO Should this return @body instead? It seems more useful.
	return self
end

def close(error = nil)

@parameter error [Exception | Nil] the error that caused the stream to be closed, if any.

Close the connection as quickly as possible. Discards body. May close the underlying connection if necessary to terminate the stream.
def close(error = nil)
	if @body
		@body.close(error)
		@body = nil
	end
end

def discard

Discard the body as efficiently as possible.
def discard
	if body = @body
		@body = nil
		body.discard
	end
	
	return nil
end

def each(&block)

@yields {|chunk| ...} chunks from the body.

Read chunks from the body.
def each(&block)
	if @body
		@body.each(&block)
		@body = nil
	end
end

def finish

@returns [Buffered] buffers the entire body.

Gracefully finish reading the body. This will buffer the remainder of the body.
def finish
	if @body
		body = @body.finish
		@body = nil
		
		return body
	end
end

def read

@returns [String] the entire body as a string.

Reads the entire request/response body.
def read
	if @body
		buffer = @body.join
		@body = nil
		
		return buffer
	end
end

def save(path, mode = ::File::WRONLY|::File::CREAT|::File::TRUNC, **options)

@parameter options [Hash] additional options to pass to `File.open`.
@parameter mode [Integer] the mode to open the file with.
@parameter path [String] the path to write the body to.

Write the body of the response to the given file path.
def save(path, mode = ::File::WRONLY|::File::CREAT|::File::TRUNC, **options)
	if @body
		::File.open(path, mode, **options) do |file|
			self.each do |chunk|
				file.write(chunk)
			end
		end
	end
end