Skip to content

Commit

Permalink
Move file/directory related methods to Path
Browse files Browse the repository at this point in the history
This moves various methods for copying files and managing directories
into the Path type, instead of them being spread across std.fs.dir and
std.fs.file as module methods. This results in all path related logic
being contained in the Path type.

This fixes #586 and fixes
#587.

Changelog: changed
  • Loading branch information
yorickpeterse committed Jul 21, 2023
1 parent bc1273c commit 5ce44a5
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 278 deletions.
124 changes: 0 additions & 124 deletions std/src/std/fs/dir.inko

This file was deleted.

51 changes: 0 additions & 51 deletions std/src/std/fs/file.inko
Expand Up @@ -14,7 +14,6 @@
import std.drop.Drop
import std.fs.path.(IntoPath, Path)
import std.io.(Error, Read, Seek, Size, Write)
import std.string.ToString

let FILE_READ_ONLY = 0
let FILE_WRITE_ONLY = 1
Expand Down Expand Up @@ -43,12 +42,6 @@ fn extern inko_file_flush(
) -> AnyResult

fn extern inko_file_drop(file: Pointer[Int8])
fn extern inko_file_copy(
state: Pointer[Int8],
process: Pointer[Int8],
from: String,
to: String,
) -> AnyResult

fn extern inko_file_open(
process: Pointer[Int8],
Expand All @@ -64,7 +57,6 @@ fn extern inko_file_read(
size: Int,
) -> IntResult

fn extern inko_file_remove(process: Pointer[Int8], path: String) -> AnyResult
fn extern inko_file_seek(
state: Pointer[Int8],
process: Pointer[Int8],
Expand Down Expand Up @@ -92,49 +84,6 @@ fn extern inko_file_write_string(
input: String,
) -> IntResult

# Removes the file for the given file path.
#
# # Examples
#
# Removing a file:
#
# import std.fs.file.(self, WriteOnlyFile)
#
# let handle = WriteOnlyFile.new('/tmp/test.txt').unwrap
#
# handle.write('hello').unwrap
# file.remove('/tmp/test.txt').unwrap
fn pub remove(path: ref ToString) -> Result[Nil, Error] {
match inko_file_remove(_INKO.process, path.to_string) {
case { @tag = 1, @value = _ } -> Result.Ok(nil)
case { @tag = _, @value = e } -> Result.Error(Error.from_os_error(e as Int))
}
}

# Copies a file from the source destination to the target destination,
# returning the number of copied bytes.
#
# # Examples
#
# Copying a file:
#
# import std.fs.file.(self, WriteOnlyFile)
#
# let handle = WriteOnlyFile.new('/tmp/test.txt').unwrap
#
# handle.write('hello').unwrap
# file.copy(from: '/tmp/test.txt', to: '/tmp/test2.txt').unwrap
fn pub copy(from: ref ToString, to: ref ToString) -> Result[Int, Error] {
match inko_file_copy(
_INKO.state, _INKO.process, from.to_string, to.to_string
) {
case { @tag = 0, @value = v } -> Result.Ok(v as Int)
case { @tag = _, @value = e } -> Result.Error(
Error.from_os_error(e as Int)
)
}
}

# A file that can only be used for reads.
class pub ReadOnlyFile {
# The path of the file.
Expand Down
169 changes: 169 additions & 0 deletions std/src/std/fs/path.inko
Expand Up @@ -20,6 +20,35 @@ class extern AnyResult {
let @value: Any
}

fn extern inko_file_remove(process: Pointer[Int8], path: String) -> AnyResult

fn extern inko_file_copy(
state: Pointer[Int8],
process: Pointer[Int8],
from: String,
to: String,
) -> AnyResult

fn extern inko_directory_remove(
process: Pointer[Int8],
path: String,
) -> AnyResult

fn extern inko_directory_create(
process: Pointer[Int8],
path: String,
) -> AnyResult

fn extern inko_directory_create_recursive(
process: Pointer[Int8],
path: String,
) -> AnyResult

fn extern inko_directory_remove_recursive(
process: Pointer[Int8],
path: String,
) -> AnyResult

fn extern inko_file_size(
state: Pointer[Int8],
process: Pointer[Int8],
Expand Down Expand Up @@ -406,6 +435,146 @@ class pub Path {
ReadDirectory { @path = @path, @inner = inner }
}
}

# Removes the file `self` points to.
#
# If `self` points to a directory, an error is returned.
#
# # Examples
#
# import std.fs.file.WriteOnlyFile
# import std.fs.path.Path
#
# let path = Path.new('/tmp/test.txt')
# let handle = WriteOnlyFile.new(path).unwrap
#
# handle.write_string('hello').unwrap
# path.remove_file.unwrap
fn pub remove_file -> Result[Nil, Error] {
match inko_file_remove(_INKO.process, @path) {
case { @tag = 1, @value = _ } -> Result.Ok(nil)
case { @tag = _, @value = e } -> Result.Error(
Error.from_os_error(e as Int)
)
}
}

# Removes the directory `self` points to.
#
# If `self` points to a file, an error is returned.
#
# # Examples
#
# import std.fs.path.Path
#
# let path = Path.new('/tmp/foo')
#
# path.create_directory.unwrap
# path.remove_directory.unwrap
fn pub remove_directory -> Result[Nil, Error] {
match inko_directory_remove(_INKO.process, @path) {
case { @tag = 1, @value = _ } -> Result.Ok(nil)
case { @tag = _, @value = e } -> Result.Error(
Error.from_os_error(e as Int)
)
}
}

# Removes the directory and its contents `self` points to.
#
# # Errors
#
# This method returns an `Error` if any of the following conditions are met:
#
# 1. The user lacks the necessary permissions to remove the directory.
# 2. The directory does not exist.
#
# # Examples
#
# Removing a directory:
#
# import std.fs.path.Path
#
# Path.new('/tmp/foo/bar').create_directory_all.unwrap
# Path.new('/tmp/foo').remove_directory_all.unwrap
fn pub remove_directory_all -> Result[Nil, Error] {
match inko_directory_remove_recursive(_INKO.process, @path) {
case { @tag = 1, @value = _ } -> Result.Ok(nil)
case { @tag = _, @value = e } -> Result.Error(
Error.from_os_error(e as Int)
)
}
}

# Creates a new empty directory at the path `self` points to.
#
# # Errors
#
# This method returns an `Error` if any of the following conditions are met:
#
# 1. The user lacks the necessary permissions to create the directory.
# 2. The directory already exists.
#
# # Examples
#
# import std.fs.path.Path
#
# Path.new('/tmp/test').create_directory.unwrap
fn pub create_directory -> Result[Nil, Error] {
match inko_directory_create(_INKO.process, @path) {
case { @tag = 1, @value = _ } -> Result.Ok(nil)
case { @tag = _, @value = e } -> Result.Error(
Error.from_os_error(e as Int)
)
}
}

# Creates a new empty directory at the path `self` points to, while also
# creating any intermediate directories.
#
# # Errors
#
# This method returns an `Error` if any of the following conditions are met:
#
# 1. The user lacks the necessary permissions to create the directory.
#
# # Examples
#
# import std.fs.path.Path
#
# Path.new('/tmp/foo/bar/test').create_directory_all.unwrap
fn pub create_directory_all -> Result[Nil, Error] {
match inko_directory_create_recursive(_INKO.process, @path) {
case { @tag = 1, @value = _ } -> Result.Ok(nil)
case { @tag = _, @value = e } -> Result.Error(
Error.from_os_error(e as Int)
)
}
}

# Copies the file `self` points to the file `to` points to, returning the
# number of copied bytes.
#
# If `self` or `to` points to a directory, an error is returned.
#
# # Examples
#
# import std.fs.file.WriteOnlyFile
# import std.fs.path.Path
#
# let path = Path.new('/tmp/test.txt')
# let file = WriteOnlyFile.new(path).unwrap
#
# file.write_string('hello').unwrap
# path.copy(to: '/tmp/test2.txt').unwrap
fn pub copy(to: ref ToString) -> Result[Int, Error] {
match inko_file_copy(_INKO.state, _INKO.process, @path, to.to_string) {
case { @tag = 0, @value = v } -> Result.Ok(v as Int)
case { @tag = _, @value = e } -> Result.Error(
Error.from_os_error(e as Int)
)
}
}
}

# A type from which a new `Path` can be created.
Expand Down

0 comments on commit 5ce44a5

Please sign in to comment.