Skip to content

Instantly share code, notes, and snippets.

@giacomocavalieri
Last active June 26, 2024 09:05
Show Gist options
  • Save giacomocavalieri/192dd30f4fe5c85b79d1bea2238e4055 to your computer and use it in GitHub Desktop.
Save giacomocavalieri/192dd30f4fe5c85b79d1bea2238e4055 to your computer and use it in GitHub Desktop.
Lines stream in Gleam
import gleam/dynamic.{type Dynamic}
import gleam/int
import gleam/io
const file = "./lines.txt"
pub fn main() {
let assert Ok(stream) = open(file)
let assert Ok(lines) = do_count_lines(stream, 0)
lines |> int.to_string |> io.println
}
fn do_count_lines(stream: FileStream, acc: Int) -> Result(Int, FileStreamError) {
case read_line(stream) {
Error(Other(reason)) -> Error(Other(reason))
Error(Eof) -> Ok(acc)
Ok(_) -> do_count_lines(stream, acc + 1)
}
}
type FileStream
type FileStreamError {
Eof
Other(Dynamic)
}
@external(erlang, "read_line_ffi", "open")
fn open(file: String) -> Result(FileStream, Nil)
@external(erlang, "read_line_ffi", "read_line")
fn read_line(stream: FileStream) -> Result(String, FileStreamError)
-module(read_line_ffi).
-export([open/1, read_line/1]).
open(File) ->
% Here we specify a couple options:
% - `raw`: allows for faster access to the file.
% - `binary`: reads the contents of the file as binary
% which is what Gleam represents Strings as.
% - `read_ahead`: this is highly recommended from
% Erlang's doc when reading line-by-line a raw file
% and allows to squeeze out a bit more performance
% reducing the number of system calls.
% - `{encoding, utf8}`: Gleam strings are utf8 encoded
% so we want to make sure what we read is a valid
% string.
case file:open(File, [raw, binary, read_ahead, {encoding, utf8}]) of
{ok, Stream} -> {ok, Stream};
{error, _} -> {error, nil}
end.
% Nothing special is going on here, we just have to
% massage `file:read_line`'s type into a Gleam result
% type.
read_line(Stream) ->
case file:read_line(Stream) of
{ok, Line} -> {ok, Line};
eof -> {error, eof};
{error, Reason} -> {error, {other, Reason}}
end.
@johtso
Copy link

johtso commented Jun 26, 2024

Jak Gleam MVP

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment