denoland / std

The Deno Standard Library
https://jsr.io/@std
MIT License
3.11k stars 614 forks source link

feature request(streams): lines(readable): AsyncIterable<string> #5071

Closed kt3k closed 2 months ago

kt3k commented 4 months ago

Idea from some discussion: A quick helper for getting an async iterable (or maybe another stream) of lines from a ReadableStream.

Example signature: lines(readable: ReadableStream<Uint8Array>|ReadableStream<string>): AsyncIterable<string>

import { lines } from "@std/streams";

const file = await Deno.open(filename);
for await (const line of lines(file.readable)) {
  console.log(line);
}
BlackAsLight commented 4 months ago

Does this not already exist via TextLineStream?

import { TextLineStream } from '@std/streams'

for await (
  const line of (await Deno.open('./deno.json'))
    .readable
    .pipeThrough(new TextEncoderStream())
    .pipeThrough(new TextLineStream())
)
  console.log(line)
iuioiua commented 4 months ago

I'm impartial to adding this. The above code snippet using TextLineStream() seems to suffice.

kt3k commented 4 months ago
import { TextLineStream } from '@std/streams'

for await (
  const line of (await Deno.open('./deno.json'))
    .readable
    .pipeThrough(new TextEncoderStream())
    .pipeThrough(new TextLineStream())
)
  console.log(line)

The above example is correct, but it looks a bit cluttered for such typical simple task, compared to other languages/runtimes.

Reading lines from a file is much simpler in other languages.

python

file = open('README.md', 'r')
for line in file.readlines():
  print(line)

perl

open(INFO, "README.md") or die();
foreach $line (<INFO>)  {   
  print $line;    
}

I think it would be useful to have special/ergonomic wrapper for such typical task

BlackAsLight commented 4 months ago

If something like this is to be added, I think a toLines(stream) to align with toText and toJSON would be best. Although on the other hand somebody might assume it would return an iterable of strings instead of an async iterable of strings.

kt3k commented 4 months ago

toLines sounds good to me

jsejcksn commented 3 months ago

I agree with the comment by @iuioiua — this seems convenient, but also somewhat trivial.

If it is decided to be added, I think that the return type should be ReadableStream<string> to provide more convenience value: it already implements AsyncIterable<string> and can also be piped, etc.