diff --git a/fs/fs.wasm-gc.mbt b/fs/fs.wasm-gc.mbt new file mode 100644 index 0000000..d1c62e9 --- /dev/null +++ b/fs/fs.wasm-gc.mbt @@ -0,0 +1,75 @@ +/// Reads the contents of a file into a string. +/// +/// # Parameters +/// - `path`: An `ExternString` representing the file path. +/// +/// # Returns +/// An `ExternString` containing the file contents. +/// +/// # Note +/// This is an unstable function call and should be used internally only. +fn read_file_to_string(path : @ffi.ExternString) -> @ffi.ExternString = "__moonbit_fs_unstable" "read_file_to_string" + +/// Writes a string to a file. +/// +/// # Parameters +/// - `path`: An `ExternString` representing the file path. +/// - `content`: An `ExternString` containing the content to be written to the file. +/// +/// # Note +/// This is an unstable function call and should be used internally only. +fn write_string_to_file(path : @ffi.ExternString, content : @ffi.ExternString) = "__moonbit_fs_unstable" "write_string_to_file" + +/// Checks if a path exists. +/// +/// # Parameters +/// - `path`: An `ExternString` representing the file path. +/// +/// # Returns +/// A boolean indicating whether the path exists. +/// +/// # Note +/// This is an unstable function call and should be used internally only. +fn path_exists(path : @ffi.ExternString) -> Bool = "__moonbit_fs_unstable" "path_exists" + +fn read_to_string(path : String) -> String { + let content = read_file_to_string(@ffi.string_to_extern(path)) + @ffi.string_from_extern(content) +} + +/// 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_to_string(path : String, content : String) -> Unit { + write_string_to_file( + @ffi.string_to_extern(path), + @ffi.string_to_extern(content), + ) +} + +/// Checks if a path exists. +/// +/// # Parameters +/// - `path`: A `String` representing the file path. +/// +/// # Returns +/// A boolean indicating whether the path exists. +pub fn exists(path : String) -> Bool { + path_exists(@ffi.string_to_extern(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_all(path : String) -> String! { + if not(exists(path)) { + fail!("File does not exist") + } + read_to_string(path) +} diff --git a/fs/internal/ffi/array.wasm-gc.mbt b/fs/internal/ffi/array.wasm-gc.mbt new file mode 100644 index 0000000..0c6b18f --- /dev/null +++ b/fs/internal/ffi/array.wasm-gc.mbt @@ -0,0 +1,9 @@ +pub type JSArray + +pub fn array_len(arr : JSArray) -> Int = "__moonbit_fs_unstable" "array_len" + +pub fn array_get(arr : JSArray, idx : Int) -> JSValue = "__moonbit_fs_unstable" "array_get" + +pub fn JSArray::op_get(self : JSArray, idx : Int) -> JSValue { + return array_get(self, idx) +} diff --git a/fs/internal/ffi/jsvalue.wasm-gc.mbt b/fs/internal/ffi/jsvalue.wasm-gc.mbt new file mode 100644 index 0000000..3545a88 --- /dev/null +++ b/fs/internal/ffi/jsvalue.wasm-gc.mbt @@ -0,0 +1,5 @@ +type JSValue + +pub fn jsvalue_is_string(v : JSValue) -> Bool = "__moonbit_fs_unstable" "jsvalue_is_string" + +pub fn jsvalue_get_string(v : JSValue) -> ExternString = "%identity" diff --git a/fs/internal/ffi/moon.pkg.json b/fs/internal/ffi/moon.pkg.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/fs/internal/ffi/moon.pkg.json @@ -0,0 +1 @@ +{} diff --git a/fs/internal/ffi/string.wasm-gc.mbt b/fs/internal/ffi/string.wasm-gc.mbt new file mode 100644 index 0000000..fb97827 --- /dev/null +++ b/fs/internal/ffi/string.wasm-gc.mbt @@ -0,0 +1,40 @@ +type StringCreateHandle + +type StringReadHandle + +pub type ExternString + +fn begin_create_string() -> StringCreateHandle = "__moonbit_fs_unstable" "begin_create_string" + +fn string_append_char(handle : StringCreateHandle, ch : Char) = "__moonbit_fs_unstable" "string_append_char" + +fn finish_create_string(handle : StringCreateHandle) -> ExternString = "__moonbit_fs_unstable" "finish_create_string" + +pub fn string_to_extern(s : String) -> ExternString { + let handle = begin_create_string() + s.iter().each(fn(ch) { string_append_char(handle, ch) }) + finish_create_string(handle) +} + +fn begin_read_string(s : ExternString) -> StringReadHandle = "__moonbit_fs_unstable" "begin_read_string" + +/// Read one char from the string, returns -1 if the end of the string is reached. +/// The number returned is the unicode codepoint of the character. +fn string_read_char(handle : StringReadHandle) -> Int = "__moonbit_fs_unstable" "string_read_char" + +fn finish_read_string(handle : StringReadHandle) = "__moonbit_fs_unstable" "finish_read_string" + +pub fn string_from_extern(e : ExternString) -> String { + let buf = Buffer::new() + let handle = begin_read_string(e) + while true { + let ch = string_read_char(handle) + if ch == -1 { + break + } else { + buf.write_char(Char::from_int(ch)) + } + } + finish_read_string(handle) + buf.to_string() +} diff --git a/fs/internal/moon.pkg.json b/fs/internal/moon.pkg.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/fs/internal/moon.pkg.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/fs/moon.pkg.json b/fs/moon.pkg.json new file mode 100644 index 0000000..01514af --- /dev/null +++ b/fs/moon.pkg.json @@ -0,0 +1,5 @@ +{ + "import": [ + "moonbitlang/x/fs/internal/ffi" + ] +}