mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-10 22:06:17 +00:00
144 lines
5.8 KiB
Text
144 lines
5.8 KiB
Text
interface File
|
|
exposes [ReadErr, WriteErr, write, writeUtf8, writeBytes, readUtf8, readBytes, delete]
|
|
imports [Task.{ Task }, InternalTask, InternalFile, Path.{ Path }, InternalPath, Effect.{ Effect }]
|
|
|
|
ReadErr : InternalFile.ReadErr
|
|
|
|
WriteErr : InternalFile.WriteErr
|
|
|
|
## Encodes a value using the given `EncodingFormat` and writes it to a file.
|
|
##
|
|
## For example, suppose you have a [JSON](https://en.wikipedia.org/wiki/JSON)
|
|
## `EncodingFormat` named `Json.toCompactUtf8`. Then you can use that format
|
|
## to write some encodable data to a file as JSON, like so:
|
|
##
|
|
## File.write
|
|
## (Path.fromStr "output.json")
|
|
## { some: "json stuff" }
|
|
## Json.toCompactUtf8
|
|
## # Writes the following to the file `output.json`:
|
|
## #
|
|
## # {"some":"json stuff"}
|
|
##
|
|
## If writing to the file fails, for example because of a file permissions issue,
|
|
## the task fails with [WriteErr].
|
|
##
|
|
## This opens the file first and closes it after writing to it.
|
|
##
|
|
## To write unformatted bytes to a file, you can use [File.writeBytes] instead.
|
|
write : Path, val, fmt -> Task {} [FileWriteErr Path WriteErr] | val has Encode.Encoding, fmt has Encode.EncoderFormatting
|
|
write = \path, val, fmt ->
|
|
bytes = Encode.toBytes val fmt
|
|
|
|
# TODO handle encoding errors here, once they exist
|
|
writeBytes path bytes
|
|
|
|
## Writes bytes to a file.
|
|
##
|
|
## # Writes the bytes 1, 2, 3 to the file `myfile.dat`.
|
|
## File.writeBytes (Path.fromStr "myfile.dat") [1, 2, 3]
|
|
##
|
|
## This opens the file first and closes it after writing to it.
|
|
##
|
|
## To format data before writing it to a file, you can use [File.write] instead.
|
|
writeBytes : Path, List U8 -> Task {} [FileWriteErr Path WriteErr]
|
|
writeBytes = \path, bytes ->
|
|
toWriteTask path \pathBytes -> Effect.fileWriteBytes pathBytes bytes
|
|
|
|
## Writes a [Str] to a file, encoded as [UTF-8](https://en.wikipedia.org/wiki/UTF-8).
|
|
##
|
|
## # Writes "Hello!" encoded as UTF-8 to the file `myfile.txt`.
|
|
## File.writeUtf8 (Path.fromStr "myfile.txt") "Hello!"
|
|
##
|
|
## This opens the file first and closes it after writing to it.
|
|
##
|
|
## To write unformatted bytes to a file, you can use [File.writeBytes] instead.
|
|
writeUtf8 : Path, Str -> Task {} [FileWriteErr Path WriteErr]
|
|
writeUtf8 = \path, str ->
|
|
toWriteTask path \bytes -> Effect.fileWriteUtf8 bytes str
|
|
|
|
## Deletes a file from the filesystem.
|
|
##
|
|
## # Deletes the file named
|
|
## File.delete (Path.fromStr "myfile.dat") [1, 2, 3]
|
|
##
|
|
## Note that this does not securely erase the file's contents from disk; instead, the operating
|
|
## system marks the space it was occupying as safe to write over in the future. Also, the operating
|
|
## system may not immediately mark the space as free; for example, on Windows it will wait until
|
|
## the last file handle to it is closed, and on UNIX, it will not remove it until the last
|
|
## [hard link](https://en.wikipedia.org/wiki/Hard_link) to it has been deleted.
|
|
##
|
|
## This performs a [`DeleteFile`](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-deletefile)
|
|
## on Windows and [`unlink`](https://en.wikipedia.org/wiki/Unlink_(Unix)) on UNIX systems.
|
|
##
|
|
## On Windows, this will fail when attempting to delete a readonly file; the file's
|
|
## readonly permission must be disabled before it can be successfully deleted.
|
|
delete : Path -> Task {} [FileWriteErr Path WriteErr]
|
|
delete = \path ->
|
|
toWriteTask path \bytes -> Effect.fileDelete bytes
|
|
|
|
## Reads all the bytes in a file.
|
|
##
|
|
## # Read all the bytes in `myfile.txt`.
|
|
## File.readBytes (Path.fromStr "myfile.txt")
|
|
##
|
|
## This opens the file first and closes it after reading its contents.
|
|
##
|
|
## To read and decode data from a file, you can use `File.read` instead.
|
|
readBytes : Path -> Task (List U8) [FileReadErr Path ReadErr]
|
|
readBytes = \path ->
|
|
toReadTask path \bytes -> Effect.fileReadBytes bytes
|
|
|
|
## Reads a [Str] from a file containing [UTF-8](https://en.wikipedia.org/wiki/UTF-8)-encoded text.
|
|
##
|
|
## # Reads UTF-8 encoded text into a `Str` from the file `myfile.txt`.
|
|
## File.readUtf8 (Path.fromStr "myfile.txt")
|
|
##
|
|
## This opens the file first and closes it after writing to it.
|
|
## The task will fail with `FileReadUtf8Err` if the given file contains invalid UTF-8.
|
|
##
|
|
## To read unformatted bytes from a file, you can use [File.readBytes] instead.
|
|
readUtf8 :
|
|
Path
|
|
-> Task Str [FileReadErr Path ReadErr, FileReadUtf8Err Path _]
|
|
readUtf8 = \path ->
|
|
effect = Effect.map (Effect.fileReadBytes (InternalPath.toBytes path)) \result ->
|
|
when result is
|
|
Ok bytes ->
|
|
Str.fromUtf8 bytes
|
|
|> Result.mapErr \err -> FileReadUtf8Err path err
|
|
|
|
Err readErr -> Err (FileReadErr path readErr)
|
|
|
|
InternalTask.fromEffect effect
|
|
|
|
# read :
|
|
# Path,
|
|
# fmt
|
|
# -> Task
|
|
# Str
|
|
# [FileReadErr Path ReadErr, FileReadDecodeErr Path [Leftover (List U8)]Decode.DecodeError ]
|
|
# [Read [File]]
|
|
# | val has Decode.Decoding, fmt has Decode.DecoderFormatting
|
|
# read = \path, fmt ->
|
|
# effect = Effect.map (Effect.fileReadBytes (InternalPath.toBytes path)) \result ->
|
|
# when result is
|
|
# Ok bytes ->
|
|
# when Decode.fromBytes bytes fmt is
|
|
# Ok val -> Ok val
|
|
# Err decodingErr -> Err (FileReadDecodeErr decodingErr)
|
|
# Err readErr -> Err (FileReadErr readErr)
|
|
# InternalTask.fromEffect effect
|
|
toWriteTask : Path, (List U8 -> Effect (Result ok err)) -> Task ok [FileWriteErr Path err]
|
|
toWriteTask = \path, toEffect ->
|
|
InternalPath.toBytes path
|
|
|> toEffect
|
|
|> InternalTask.fromEffect
|
|
|> Task.mapFail \err -> FileWriteErr path err
|
|
|
|
toReadTask : Path, (List U8 -> Effect (Result ok err)) -> Task ok [FileReadErr Path err]
|
|
toReadTask = \path, toEffect ->
|
|
InternalPath.toBytes path
|
|
|> toEffect
|
|
|> InternalTask.fromEffect
|
|
|> Task.mapFail \err -> FileReadErr path err
|