-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add multi backend support for fs io (#59)
* wasm * js * basiclly done * add comment * moon info * use Bytes instead of Array[Byte] * use guard and type! * moon fmt * enable coverage-check-bleeding * bump version * polish error show msg
- Loading branch information
1 parent
83230f0
commit 3a09c6d
Showing
17 changed files
with
626 additions
and
168 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
// Copyright 2024 International Digital Economy Academy | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
pub type! IOError { | ||
NotFound(String) | ||
} | ||
|
||
pub impl Show for IOError with output(self, logger) { | ||
logger.write_string(self.to_string()) | ||
} | ||
|
||
fn IOError::to_string(self : IOError) -> String { | ||
match self { | ||
IOError::NotFound(path) => "`\{path}` does not exist" | ||
} | ||
} | ||
|
||
/// Writes a string to a file. | ||
/// | ||
/// # Parameters | ||
/// - `path`: A `String` representing the file path. | ||
/// - `content`: A `String` containing the content to be written to the file. | ||
pub fn write_string_to_file(~path : String, ~content : String) -> Unit { | ||
@ffi.write_string_to_file(path, content) | ||
} | ||
|
||
/// Writes an array of bytes to a file at the specified path. | ||
/// | ||
/// # Parameters | ||
/// | ||
/// - `path` : The path to the file where the bytes will be written. | ||
/// - `content` : An array of bytes to be written to the file. | ||
pub fn write_bytes_to_file(~path : String, ~content : Bytes) -> Unit { | ||
@ffi.write_bytes_to_file(path, content) | ||
} | ||
|
||
/// Checks if a path exists. | ||
/// | ||
/// # Parameters | ||
/// - `path`: A `String` representing the file path. | ||
/// | ||
/// # Returns | ||
/// A boolean indicating whether the path exists. | ||
pub fn path_exists(~path : String) -> Bool { | ||
@ffi.path_exists(path) | ||
} | ||
|
||
/// Reads the entire contents of a file into a string. | ||
/// | ||
/// # Parameters | ||
/// - `path`: A `String` representing the file path. | ||
/// | ||
/// # Returns | ||
/// A `String` containing the file contents if the file exists, otherwise raises an error. | ||
pub fn read_file_to_string(~path : String) -> String! { | ||
guard path_exists(~path) else { raise IOError::NotFound(path) } | ||
@ffi.read_file_to_string(path) | ||
} | ||
|
||
/// Reads the content of a file specified by the given path and returns its | ||
/// content as an array of bytes. If the file does not exist, an error is raised. | ||
/// | ||
/// # Parameters | ||
/// | ||
/// - `path` : The path to the file to be read. | ||
/// | ||
/// # Returns | ||
/// | ||
/// - An array of bytes representing the content of the file. | ||
pub fn read_file_to_bytes(~path : String) -> Bytes! { | ||
guard path_exists(~path) else { raise IOError::NotFound(path) } | ||
@ffi.read_file_to_bytes(path) | ||
} | ||
|
||
/// Reads the contents of a directory and returns an array of filenames. | ||
/// | ||
/// # Parameters | ||
/// | ||
/// - `path` : The path to the directory to be read. | ||
/// | ||
/// # Returns | ||
/// | ||
/// - An array of strings representing the file name and directory name in the directory. | ||
pub fn read_dir(~path : String) -> Array[String]! { | ||
guard path_exists(~path) else { raise IOError::NotFound(path) } | ||
@ffi.read_dir(path) | ||
} | ||
|
||
/// Creates a directory at the specified path. | ||
/// | ||
/// # Parameters | ||
/// | ||
/// - `path` : The path where the directory should be created. | ||
pub fn create_dir(~path : String) -> Unit { | ||
@ffi.create_dir(path) | ||
} | ||
|
||
/// Checks if the given path is a directory. | ||
/// | ||
/// # Parameters | ||
/// | ||
/// - `path` : The string representing the path to be checked. | ||
/// | ||
/// # Returns | ||
/// | ||
/// - `Bool` : `true` if the path is a directory, `false` otherwise. | ||
pub fn is_dir(~path : String) -> Bool! { | ||
guard path_exists(~path) else { raise IOError::NotFound(path) } | ||
@ffi.is_dir(path) | ||
} | ||
|
||
/// Check if the given path points to a file. | ||
/// | ||
/// # Parameters | ||
/// | ||
/// - `path` : The string representing the path to be checked. | ||
/// | ||
/// # Returns | ||
/// | ||
/// - `Bool` : `true` if the path points to a file, `false` otherwise. | ||
pub fn is_file(~path : String) -> Bool! { | ||
guard path_exists(~path) else { raise IOError::NotFound(path) } | ||
@ffi.is_file(path) | ||
} | ||
|
||
/// Removes a directory at the specified path. | ||
/// | ||
/// # Parameters | ||
/// | ||
/// - `path` : The string path to the directory that needs to be removed. | ||
pub fn remove_dir(~path : String) -> Unit! { | ||
guard path_exists(~path) else { raise IOError::NotFound(path) } | ||
@ffi.remove_dir(path) | ||
} | ||
|
||
/// Removes a file at the specified path. | ||
/// | ||
/// # Parameters | ||
/// | ||
/// - `path` : The path to the file that needs to be removed. | ||
pub fn remove_file(~path : String) -> Unit! { | ||
guard path_exists(~path) else { raise IOError::NotFound(path) } | ||
@ffi.remove_file(path) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,37 @@ | ||
package moonbitlang/x/fs | ||
|
||
// Values | ||
fn exists(~path : String) -> Bool | ||
fn create_dir(~path : String) -> Unit | ||
|
||
fn read_to_string(~path : String) -> String! | ||
fn is_dir(~path : String) -> Bool! | ||
|
||
fn write_string(~path : String, ~content : String) -> Unit | ||
fn is_file(~path : String) -> Bool! | ||
|
||
fn path_exists(~path : String) -> Bool | ||
|
||
fn read_dir(~path : String) -> Array[String]! | ||
|
||
fn read_file_to_bytes(~path : String) -> Bytes! | ||
|
||
fn read_file_to_string(~path : String) -> String! | ||
|
||
fn remove_dir(~path : String) -> Unit! | ||
|
||
fn remove_file(~path : String) -> Unit! | ||
|
||
fn write_bytes_to_file(~path : String, ~content : Bytes) -> Unit | ||
|
||
fn write_string_to_file(~path : String, ~content : String) -> Unit | ||
|
||
// Types and methods | ||
pub type! IOError { | ||
NotFound(String) | ||
} | ||
|
||
// Type aliases | ||
|
||
// Traits | ||
|
||
// Extension Methods | ||
impl Show for IOError | ||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Copyright 2024 International Digital Economy Academy | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
test "write_and_read" { | ||
let path = "1.txt" | ||
@fs.write_string_to_file( | ||
path="1.txt", | ||
content= | ||
#|target/ | ||
#|.mooncakes/ | ||
#| | ||
, | ||
) | ||
assert_true!(@fs.path_exists(~path)) | ||
let byte = @fs.read_file_to_bytes!(~path).iter().map(fn(x) { x.to_uint() }) | ||
inspect!( | ||
byte, | ||
content="[116, 97, 114, 103, 101, 116, 47, 10, 46, 109, 111, 111, 110, 99, 97, 107, 101, 115, 47, 10]", | ||
) | ||
@fs.remove_file!(~path) | ||
assert_false!(@fs.path_exists(~path)) | ||
try { | ||
@fs.read_file_to_string!(~path) |> ignore | ||
} catch { | ||
@fs.IOError::NotFound(_) as e => | ||
inspect!(e, content="`1.txt` does not exist") | ||
_ => return | ||
} | ||
let bytes = Bytes::from_array([65, 97].map(fn(x) { x.to_byte() })) | ||
@fs.write_bytes_to_file(~path, content=bytes) | ||
assert_true!(@fs.path_exists(~path)) | ||
let content = @fs.read_file_to_string!(~path) | ||
inspect!(content, content="Aa") | ||
@fs.remove_file!(~path) | ||
assert_false!(@fs.path_exists(~path)) | ||
try { | ||
@fs.remove_file!(~path) |> ignore | ||
} catch { | ||
@fs.IOError::NotFound(_) as e => | ||
inspect!(e, content="`1.txt` does not exist") | ||
_ => return | ||
} | ||
} | ||
|
||
test "path_exist" { | ||
// dir exist | ||
assert_true!(@fs.path_exists(path=".github")) | ||
// dir don't exist | ||
assert_false!(@fs.path_exists(path="no_exist")) | ||
|
||
// file exist | ||
assert_true!(@fs.path_exists(path=".gitignore")) | ||
|
||
// file don't exist | ||
assert_false!(@fs.path_exists(path="no_exist.txt")) | ||
} | ||
|
||
test "create_and_remove_dir" { | ||
@fs.create_dir(path="hello/1/12.txt") | ||
assert_true!(@fs.path_exists(path="hello/1/12.txt")) | ||
@fs.remove_dir!(path="hello") | ||
assert_false!(@fs.path_exists(path="hello")) | ||
try { | ||
@fs.remove_dir!(path="hello") |> ignore | ||
} catch { | ||
@fs.IOError::NotFound(_) as e => | ||
inspect!(e, content="`hello` does not exist") | ||
_ => return | ||
} | ||
} | ||
|
||
test "read_dir" { | ||
let dir_content = @fs.read_dir!(path=".")..sort() | ||
inspect!( | ||
dir_content, | ||
content= | ||
#|["fs", "num", ".git", "time", "uuid", "json5", "stack", "crypto", "target", ".github", "README.md", ".gitignore", ".mooncakes", "_typos.toml", "moon.mod.json", "licenserc.toml"] | ||
, | ||
) | ||
try { | ||
@fs.read_dir!(path="fasd") |> ignore | ||
} catch { | ||
@fs.IOError::NotFound(_) as e => | ||
inspect!(e, content="`fasd` does not exist") | ||
_ => return | ||
} | ||
} |
Oops, something went wrong.