silk.io.standard_input.
The StandardInput effect: read raw bytes from standard input.
When to use#
Require &mut StandardInput in code that reads standard input, so a test can provide the bytes.
To parse lines or other units, use silk.io.buffered_input.BufferedInput.fillStandard. Decode text
after you read the bytes, so invalid UTF-8 does not lose data.
Details#
StandardInput.receive fills a prefix of the buffer and returns the number of bytes, which
can be less than the buffer length. When the input ends, it returns an end-of-input outcome. End
of input is a normal result, not an error. After it, no later read returns bytes.
This effect is separate from silk.io.writer.Writer: a write completes or fails, but a read can
return part of the data and the input ends at some point.
Errors#
StreamReadErrorif the provider cannot complete a read.
Gotchas#
An empty buffer returns a count of 0 and does not read. It never reports end of input. Use a buffer of at least one byte.
Examples#
Provide input in a test and read it to the end#
import silk.core.effect { Effect }
import silk.io.standard_input { ReadOutcome, StandardInput, StreamReadError }
struct OneByte {
complete: bool,
}
effect fn read(self: &mut OneByte, buffer: &mut [u8]) -> ReadOutcome
! StreamReadError {
if buffer.length == 0 {
return StandardInput.filled(0)
}
if self.complete {
return StandardInput.endOfInput()
}
buffer[0] = 42
self.complete = true
return StandardInput.filled(1)
}
impl StandardInput for OneByte {
read: OneByte.read
}
pub effect fn main() -> i32
! StreamReadError {
let mut provider = OneByte { complete: false }
let mut buffer: [u8; 4] = [0, 0, 0, 0]
let first = run StandardInput.receive(&mut buffer)
|> Effect.provideMut<StandardInput>(&mut provider)
let second = run StandardInput.receive(&mut buffer)
|> Effect.provideMut<StandardInput>(&mut provider)
if StandardInput.count(&first) != 1 || buffer[0] != 42 || !StandardInput.isEndOfInput(&second) {
return 1
}
return 0
}Import as StandardInput with import silk.io.standard_input { StandardInput }.
Public declarations: 5.
StreamReadError#
pub struct StreamReadErrorThe error when a standard input provider cannot complete a read.
Implementation Debug for StreamReadError#
impl Debug for StreamReadErrorOperation debug#
effect fn debug(self: &Self, formatter: &mut Formatter) -> () ! WriterError ? &mut WriterWrites StreamReadError.
Filled#
pub struct FilledA read that put count bytes at the start of the buffer.
Field count#
pub count: usizeThe number of bytes at the start of the buffer. It can be less than the buffer length.
EndOfInput#
pub struct EndOfInputThe input ended. The buffer did not change, and no later read returns bytes.
ReadOutcome#
pub struct ReadOutcomeThe result of one read: a count of bytes, or end of input.
Details#
Use StandardInput.count and StandardInput.isEndOfInput, or match on value. After a
Filled result, bytes after the count keep their earlier values.
Field value#
pub value: Filled | EndOfInputThe count of bytes, or end of input.
StandardInput#
pub service StandardInputThe effect that reads raw bytes from standard input.
When to use#
Require &mut StandardInput in code that reads standard input, so a test can provide the bytes.
To parse lines or other units, use silk.io.buffered_input.BufferedInput.fillStandard. Decode text
after you read the bytes, so invalid UTF-8 does not lose data.
Details#
A provider implements read. Callers use StandardInput.receive, which fills a prefix of the
buffer and can return fewer bytes than the buffer length. End of input is a normal result, not
an error. After it, no later read returns bytes.
Operation read#
effect fn read(
buffer: &mut [u8]
) -> ReadOutcome ! StreamReadError ? &mut StandardInputReads up to buffer.length bytes into the start of buffer.
Details#
A provider changes only the bytes that it reports. For a non-empty buffer, it returns at least one byte, or end of input. After end of input, no later read returns bytes.
Errors#
StreamReadErrorif the provider cannot read.
Gotchas#
For an empty buffer, a provider must return a count of 0 and not read, also after end of input.
Implementation StandardInput#
impl StandardInputAssociated function readFailure#
pub fn readFailure() -> StreamReadErrorReturns a StreamReadError. Providers use it when a read fails.
Associated function filled#
pub fn filled(count: usize) -> ReadOutcomeReturns the outcome for a read that put count bytes in the buffer. Providers use it.
Gotchas#
count must not be more than the length of the buffer.
Associated function endOfInput#
pub fn endOfInput() -> ReadOutcomeReturns the end-of-input outcome. Providers use it.
Associated function count#
pub fn count(outcome: &ReadOutcome) -> usizeReturns the number of bytes that the read put in the buffer. Returns 0 for end of input.
Gotchas#
A count of 0 does not mean end of input. Use StandardInput.isEndOfInput to decide if more
reads can return bytes.
Associated function isEndOfInput#
pub fn isEndOfInput(outcome: &ReadOutcome) -> boolReturns true if the input ended, so no later read returns bytes.
Associated function receive#
pub effect fn receive(
buffer: &mut [u8]
) -> ReadOutcome ! StreamReadError ? &mut StandardInputReads up to buffer.length bytes from the active provider into the start of buffer.
Details#
Read only the first StandardInput.count bytes of the buffer. Read again until
StandardInput.isEndOfInput returns true to get all input.
Errors#
StreamReadErrorif the provider cannot read.
Gotchas#
Use a non-empty buffer. An empty buffer never reports end of input.
Category: Input and output.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.