module IO::Stream::Writable

def <<(string)

@parameter string [String] the string to write to the stream.
Appends `string` to the buffer and returns self for method chaining.
def <<(string)
	write(string)
	
	return self
end

def close_write

Close the write end of the stream by flushing any remaining data.
def close_write
	flush
end

def drain(buffer)

def drain(buffer)
te(buffer)
he write operation fails, we still need to clear this buffer, and the data is essentially lost.
.clear

def flush

Flushes buffered data to the stream.
def flush
	return if @write_buffer.empty?
	
	@writing.synchronize do
		self.drain(@write_buffer)
	end
end

def initialize(minimum_write_size: MINIMUM_WRITE_SIZE, **, &block)

@parameter minimum_write_size [Integer] The minimum buffer size before flushing.
Initialize writable stream functionality.
def initialize(minimum_write_size: MINIMUM_WRITE_SIZE, **, &block)
	@writing = ::Thread::Mutex.new
	@write_buffer = StringBuffer.new
	@minimum_write_size = minimum_write_size
	
	super(**, &block) if defined?(super)
end

def puts(*arguments, separator: $/)

@parameter separator [String] The separator to append after each argument.
@parameter arguments [Array] The arguments to write to the stream.
Write arguments to the stream followed by a separator and flush immediately.
def puts(*arguments, separator: $/)
	return if arguments.empty?
	
	@writing.synchronize do
		arguments.each do |argument|
			@write_buffer << argument << separator
		end
		
		self.drain(@write_buffer)
	end
end

def write(string, flush: false)

@returns [Integer] the number of bytes appended to the buffer.
@parameter string [String] the string to write to the buffer.
buffer is flushed to the underlying `io`.
Writes `string` to the buffer. When the buffer is full or #sync is true the
def write(string, flush: false)
	@writing.synchronize do
		@write_buffer << string
		
		flush |= (@write_buffer.bytesize >= @minimum_write_size)
		
		if flush
			self.drain(@write_buffer)
		end
	end
	
	return string.bytesize
end