diff options
Diffstat (limited to 'src/bun.js/node/node_fs_binding.zig')
-rw-r--r-- | src/bun.js/node/node_fs_binding.zig | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/src/bun.js/node/node_fs_binding.zig b/src/bun.js/node/node_fs_binding.zig new file mode 100644 index 000000000..298727fb9 --- /dev/null +++ b/src/bun.js/node/node_fs_binding.zig @@ -0,0 +1,423 @@ +const JSC = @import("../../jsc.zig"); +const std = @import("std"); +const Flavor = JSC.Node.Flavor; +const ArgumentsSlice = JSC.Node.ArgumentsSlice; +const system = std.os.system; +const Maybe = JSC.Maybe; +const Encoding = JSC.Node.Encoding; +const FeatureFlags = @import("../../global.zig").FeatureFlags; +const Args = JSC.Node.NodeFS.Arguments; +const d = JSC.d; + +const NodeFSFunction = fn ( + *JSC.Node.NodeFS, + JSC.C.JSContextRef, + JSC.C.JSObjectRef, + JSC.C.JSObjectRef, + []const JSC.C.JSValueRef, + JSC.C.ExceptionRef, +) JSC.C.JSValueRef; + +pub const toJSTrait = std.meta.trait.hasFn("toJS"); +pub const fromJSTrait = std.meta.trait.hasFn("fromJS"); +const NodeFSFunctionEnum = JSC.Node.DeclEnum(JSC.Node.NodeFS); + +fn callSync(comptime FunctionEnum: NodeFSFunctionEnum) NodeFSFunction { + const Function = @field(JSC.Node.NodeFS, @tagName(FunctionEnum)); + const FunctionType = @TypeOf(Function); + + const function: std.builtin.TypeInfo.Fn = comptime @typeInfo(FunctionType).Fn; + comptime if (function.args.len != 3) @compileError("Expected 3 arguments"); + const Arguments = comptime function.args[1].arg_type.?; + const FormattedName = comptime [1]u8{std.ascii.toUpper(@tagName(FunctionEnum)[0])} ++ @tagName(FunctionEnum)[1..]; + const Result = comptime JSC.Maybe(@field(JSC.Node.NodeFS.ReturnType, FormattedName)); + + const NodeBindingClosure = struct { + pub fn bind( + this: *JSC.Node.NodeFS, + ctx: JSC.C.JSContextRef, + _: JSC.C.JSObjectRef, + _: JSC.C.JSObjectRef, + arguments: []const JSC.C.JSValueRef, + exception: JSC.C.ExceptionRef, + ) JSC.C.JSValueRef { + var slice = ArgumentsSlice.init(ctx.bunVM(), @ptrCast([*]const JSC.JSValue, arguments.ptr)[0..arguments.len]); + defer slice.deinit(); + + const args = if (comptime Arguments != void) + (Arguments.fromJS(ctx, &slice, exception) orelse return null) + else + Arguments{}; + if (exception.* != null) return null; + + const result: Result = Function( + this, + args, + comptime Flavor.sync, + ); + return switch (result) { + .err => |err| brk: { + exception.* = err.toJS(ctx); + break :brk null; + }, + .result => |res| if (comptime Result.ReturnType != void) + JSC.To.JS.withType(Result.ReturnType, res, ctx, exception) + else + JSC.C.JSValueMakeUndefined(ctx), + }; + } + }; + + return NodeBindingClosure.bind; +} + +fn call(comptime Function: NodeFSFunctionEnum) NodeFSFunction { + // const FunctionType = @TypeOf(Function); + _ = Function; + + // const function: std.builtin.TypeInfo.Fn = comptime @typeInfo(FunctionType).Fn; + // comptime if (function.args.len != 3) @compileError("Expected 3 arguments"); + // const Arguments = comptime function.args[2].arg_type orelse @compileError(std.fmt.comptimePrint("Function {s} expected to have an arg type at [2]", .{@typeName(FunctionType)})); + // const Result = comptime function.return_type.?; + // comptime if (Arguments != void and !fromJSTrait(Arguments)) @compileError(std.fmt.comptimePrint("{s} is missing fromJS()", .{@typeName(Arguments)})); + // comptime if (Result != void and !toJSTrait(Result)) @compileError(std.fmt.comptimePrint("{s} is missing toJS()", .{@typeName(Result)})); + const NodeBindingClosure = struct { + pub fn bind( + this: *JSC.Node.NodeFS, + ctx: JSC.C.JSContextRef, + _: JSC.C.JSObjectRef, + _: JSC.C.JSObjectRef, + arguments: []const JSC.C.JSValueRef, + exception: JSC.C.ExceptionRef, + ) JSC.C.JSValueRef { + _ = this; + _ = ctx; + _ = arguments; + var err = JSC.SystemError{}; + exception.* = err.toErrorInstance(ctx.ptr()).asObjectRef(); + return null; + // var slice = ArgumentsSlice.init(arguments); + + // defer { + // for (arguments.len) |arg| { + // JSC.C.JSValueUnprotect(ctx, arg); + // } + // slice.arena.deinit(); + // } + + // const args = if (comptime Arguments != void) + // Arguments.fromJS(ctx, &slice, exception) + // else + // Arguments{}; + // if (exception.* != null) return null; + + // const result: Maybe(Result) = Function(this, comptime Flavor.sync, args); + // switch (result) { + // .err => |err| { + // exception.* = err.toJS(ctx); + // return null; + // }, + // .result => |res| { + // return switch (comptime Result) { + // void => JSC.JSValue.jsUndefined().asRef(), + // else => res.toJS(ctx), + // }; + // }, + // } + // unreachable; + } + }; + return NodeBindingClosure.bind; +} + +pub const NodeFSBindings = JSC.NewClass( + JSC.Node.NodeFS, + .{ .name = "fs", .ts = .{ .module = .{ .path = "fs" } } }, + + .{ + .access = .{ + .name = "access", + .rfn = call(.access), + }, + .appendFile = .{ + .name = "appendFile", + .rfn = call(.appendFile), + }, + .close = .{ + .name = "close", + .rfn = call(.close), + }, + .copyFile = .{ + .name = "copyFile", + .rfn = call(.copyFile), + }, + .exists = .{ + .name = "exists", + .rfn = call(.exists), + }, + .chown = .{ + .name = "chown", + .rfn = call(.chown), + }, + .chmod = .{ + .name = "chmod", + .rfn = call(.chmod), + }, + .fchmod = .{ + .name = "fchmod", + .rfn = call(.fchmod), + }, + .fchown = .{ + .name = "fchown", + .rfn = call(.fchown), + }, + .fstat = .{ + .name = "fstat", + .rfn = call(.fstat), + }, + .fsync = .{ + .name = "fsync", + .rfn = call(.fsync), + }, + .ftruncate = .{ + .name = "ftruncate", + .rfn = call(.ftruncate), + }, + .futimes = .{ + .name = "futimes", + .rfn = call(.futimes), + }, + .lchmod = .{ + .name = "lchmod", + .rfn = call(.lchmod), + }, + .lchown = .{ + .name = "lchown", + .rfn = call(.lchown), + }, + .link = .{ + .name = "link", + .rfn = call(.link), + }, + .lstat = .{ + .name = "lstat", + .rfn = call(.lstat), + }, + .mkdir = .{ + .name = "mkdir", + .rfn = call(.mkdir), + }, + .mkdtemp = .{ + .name = "mkdtemp", + .rfn = call(.mkdtemp), + }, + .open = .{ + .name = "open", + .rfn = call(.open), + }, + .read = .{ + .name = "read", + .rfn = call(.read), + }, + .write = .{ + .name = "write", + .rfn = call(.write), + }, + .readdir = .{ + .name = "readdir", + .rfn = call(.readdir), + }, + .readFile = .{ + .name = "readFile", + .rfn = call(.readFile), + }, + .writeFile = .{ + .name = "writeFile", + .rfn = call(.writeFile), + }, + .readlink = .{ + .name = "readlink", + .rfn = call(.readlink), + }, + .realpath = .{ + .name = "realpath", + .rfn = call(.realpath), + }, + .rename = .{ + .name = "rename", + .rfn = call(.rename), + }, + .stat = .{ + .name = "stat", + .rfn = call(.stat), + }, + .symlink = .{ + .name = "symlink", + .rfn = call(.symlink), + }, + .truncate = .{ + .name = "truncate", + .rfn = call(.truncate), + }, + .unlink = .{ + .name = "unlink", + .rfn = call(.unlink), + }, + .utimes = .{ + .name = "utimes", + .rfn = call(.utimes), + }, + .lutimes = .{ + .name = "lutimes", + .rfn = call(.lutimes), + }, + + .createReadStream = .{ + .name = "createReadStream", + .rfn = if (FeatureFlags.node_streams) callSync(.createReadStream) else call(.createReadStream), + }, + + .createWriteStream = .{ + .name = "createWriteStream", + .rfn = if (FeatureFlags.node_streams) callSync(.createWriteStream) else call(.createWriteStream), + }, + + .accessSync = .{ + .name = "accessSync", + .rfn = callSync(.access), + }, + .appendFileSync = .{ + .name = "appendFileSync", + .rfn = callSync(.appendFile), + }, + .closeSync = .{ + .name = "closeSync", + .rfn = callSync(.close), + }, + .copyFileSync = .{ + .name = "copyFileSync", + .rfn = callSync(.copyFile), + }, + .existsSync = .{ + .name = "existsSync", + .rfn = callSync(.exists), + }, + .chownSync = .{ + .name = "chownSync", + .rfn = callSync(.chown), + }, + .chmodSync = .{ + .name = "chmodSync", + .rfn = callSync(.chmod), + }, + .fchmodSync = .{ + .name = "fchmodSync", + .rfn = callSync(.fchmod), + }, + .fchownSync = .{ + .name = "fchownSync", + .rfn = callSync(.fchown), + }, + .fstatSync = .{ + .name = "fstatSync", + .rfn = callSync(.fstat), + }, + .fsyncSync = .{ + .name = "fsyncSync", + .rfn = callSync(.fsync), + }, + .ftruncateSync = .{ + .name = "ftruncateSync", + .rfn = callSync(.ftruncate), + }, + .futimesSync = .{ + .name = "futimesSync", + .rfn = callSync(.futimes), + }, + .lchmodSync = .{ + .name = "lchmodSync", + .rfn = callSync(.lchmod), + }, + .lchownSync = .{ + .name = "lchownSync", + .rfn = callSync(.lchown), + }, + .linkSync = .{ + .name = "linkSync", + .rfn = callSync(.link), + }, + .lstatSync = .{ + .name = "lstatSync", + .rfn = callSync(.lstat), + }, + .mkdirSync = .{ + .name = "mkdirSync", + .rfn = callSync(.mkdir), + }, + .mkdtempSync = .{ + .name = "mkdtempSync", + .rfn = callSync(.mkdtemp), + }, + .openSync = .{ + .name = "openSync", + .rfn = callSync(.open), + }, + .readSync = .{ + .name = "readSync", + .rfn = callSync(.read), + }, + .writeSync = .{ + .name = "writeSync", + .rfn = callSync(.write), + }, + .readdirSync = .{ + .name = "readdirSync", + .rfn = callSync(.readdir), + }, + .readFileSync = .{ + .name = "readFileSync", + .rfn = callSync(.readFile), + }, + .writeFileSync = .{ + .name = "writeFileSync", + .rfn = callSync(.writeFile), + }, + .readlinkSync = .{ + .name = "readlinkSync", + .rfn = callSync(.readlink), + }, + .realpathSync = .{ + .name = "realpathSync", + .rfn = callSync(.realpath), + }, + .renameSync = .{ + .name = "renameSync", + .rfn = callSync(.rename), + }, + .statSync = .{ + .name = "statSync", + .rfn = callSync(.stat), + }, + .symlinkSync = .{ + .name = "symlinkSync", + .rfn = callSync(.symlink), + }, + .truncateSync = .{ + .name = "truncateSync", + .rfn = callSync(.truncate), + }, + .unlinkSync = .{ + .name = "unlinkSync", + .rfn = callSync(.unlink), + }, + .utimesSync = .{ + .name = "utimesSync", + .rfn = callSync(.utimes), + }, + .lutimesSync = .{ + .name = "lutimesSync", + .rfn = callSync(.lutimes), + }, + }, + .{}, +); |