remove std.io.readLine

This was deceptive. It was always meant to be sort of a "GNU readline"
sort of thing where it provides a Command Line Interface to input text.
However that functionality did not exist and it was basically a red
herring for people trying to read line-delimited input from a stream.

In this commit the API is deleted, so that people can find the proper
API more easily.

A CLI text input abstraction would be useful but may not even need to be
in the standard library. As you can see in this commit, the guess_number
CLI game gets by just fine by using `std.fs.File.read`.
This commit is contained in:
Andrew Kelley 2020-02-20 13:43:05 -05:00
parent 3d53a95718
commit b0d2ebe529
2 changed files with 7 additions and 74 deletions

View File

@ -790,73 +790,6 @@ pub const BufferedAtomicFile = struct {
}
};
pub fn readLine(buf: *std.Buffer) ![]u8 {
var stdin_stream = getStdIn().inStream();
return readLineFrom(&stdin_stream.stream, buf);
}
/// Reads all characters until the next newline into buf, and returns
/// a slice of the characters read (excluding the newline character(s)).
pub fn readLineFrom(stream: var, buf: *std.Buffer) ![]u8 {
const start = buf.len();
while (true) {
const byte = try stream.readByte();
switch (byte) {
'\r' => {
// trash the following \n
_ = try stream.readByte();
return buf.toSlice()[start..];
},
'\n' => return buf.toSlice()[start..],
else => try buf.appendByte(byte),
}
}
}
test "io.readLineFrom" {
var buf = try std.Buffer.initSize(testing.allocator, 0);
defer buf.deinit();
var mem_stream = SliceInStream.init(
\\Line 1
\\Line 22
\\Line 333
);
const stream = &mem_stream.stream;
testing.expectEqualSlices(u8, "Line 1", try readLineFrom(stream, &buf));
testing.expectEqualSlices(u8, "Line 22", try readLineFrom(stream, &buf));
testing.expectError(error.EndOfStream, readLineFrom(stream, &buf));
testing.expectEqualSlices(u8, "Line 1Line 22Line 333", buf.toSlice());
}
pub fn readLineSlice(slice: []u8) ![]u8 {
var stdin_stream = getStdIn().inStream();
return readLineSliceFrom(&stdin_stream.stream, slice);
}
/// Reads all characters until the next newline into slice, and returns
/// a slice of the characters read (excluding the newline character(s)).
pub fn readLineSliceFrom(stream: var, slice: []u8) ![]u8 {
// We cannot use Buffer.fromOwnedSlice, as it wants to append a null byte
// after taking ownership, which would always require an allocation.
var buf = std.Buffer{ .list = std.ArrayList(u8).fromOwnedSlice(testing.failing_allocator, slice) };
try buf.resize(0);
return try readLineFrom(stream, &buf);
}
test "io.readLineSliceFrom" {
var buf: [7]u8 = undefined;
var mem_stream = SliceInStream.init(
\\Line 1
\\Line 22
\\Line 333
);
const stream = &mem_stream.stream;
testing.expectEqualSlices(u8, "Line 1", try readLineSliceFrom(stream, buf[0..]));
testing.expectError(error.OutOfMemory, readLineSliceFrom(stream, buf[0..]));
}
pub const Packing = enum {
/// Pack data to byte alignment
Byte,

View File

@ -5,6 +5,7 @@ const fmt = std.fmt;
pub fn main() !void {
const stdout = &io.getStdOut().outStream().stream;
const stdin = io.getStdIn();
try stdout.print("Welcome to the Guess Number Game in Zig.\n", .{});
@ -22,13 +23,12 @@ pub fn main() !void {
try stdout.print("\nGuess a number between 1 and 100: ", .{});
var line_buf: [20]u8 = undefined;
const line = io.readLineSlice(line_buf[0..]) catch |err| switch (err) {
error.OutOfMemory => {
try stdout.print("Input too long.\n", .{});
continue;
},
else => return err,
};
const amt = try stdin.read(&line_buf);
if (amt == line_buf.len) {
try stdout.print("Input too long.\n", .{});
continue;
}
const line = std.mem.trimRight(u8, line_buf[0..amt], "\r\n");
const guess = fmt.parseUnsigned(u8, line, 10) catch {
try stdout.print("Invalid number.\n", .{});