diff --git a/examples/ex-06.copy.zig b/examples/ex-06.copy.zig index 983fcfb..e859054 100644 --- a/examples/ex-06.copy.zig +++ b/examples/ex-06.copy.zig @@ -6,6 +6,7 @@ const TokenIter = zargs.TokenIter; const ztype = @import("ztype"); const String = ztype.String; const Open = ztype.Open; +const Read = ztype.Read; pub fn main() !void { const cmd = Command.new("copy").alias("cp") @@ -14,7 +15,7 @@ pub fn main() !void { .homepage("https://github.com/kioz-wang/zargs") .arg(Arg.opt("verbose", bool).short('v').long("verbose").help("Show detail")) .arg(Arg.optArg("max", usize).long("max").help("Max byte to copy").default(32 << 10)) - .arg(Arg.posArg("source", Open(.file, .{}))) + .arg(Arg.posArg("source", Read())) .arg(Arg.posArg("target", Open(.fileCreate, .{}))) .config(.{ .style = .classic }); @@ -28,11 +29,11 @@ pub fn main() !void { if (args.verbose) { std.debug.print("Try copy {s} to {s} with max 0x{x} bytes\n", .{ args.source.s, args.target.s, args.max }); } - const content = try args.source.v.reader().any().readAllAlloc(allocator, args.max); - defer allocator.free(content); - try args.target.v.writer().any().writeAll(content); + // const content = try args.source.v.reader().any().readAllAlloc(allocator, args.max); + // defer allocator.free(content); + try args.target.v.writer().any().writeAll(args.source.v); if (args.verbose) { - std.debug.print("Done with 0x{x} bytes\n", .{content.len}); + std.debug.print("Done with 0x{x} bytes\n", .{args.source.v.len}); } } diff --git a/src/type/base.zig b/src/type/base.zig new file mode 100644 index 0000000..9920e47 --- /dev/null +++ b/src/type/base.zig @@ -0,0 +1,2 @@ +pub const String = []const u8; +pub const LiteralString = [:0]const u8; diff --git a/src/type/checker.zig b/src/type/checker.zig index a3e21c4..695c4d3 100644 --- a/src/type/checker.zig +++ b/src/type/checker.zig @@ -1,8 +1,8 @@ const std = @import("std"); const testing = std.testing; -const String = []const u8; -const LiteralString = [:0]const u8; +const String = @import("base.zig").String; +const LiteralString = @import("base.zig").LiteralString; pub fn isBase(T: type) bool { if (T == String) return true; diff --git a/src/type/open.zig b/src/type/open.zig index cbe8d6a..76d5919 100644 --- a/src/type/open.zig +++ b/src/type/open.zig @@ -1,7 +1,7 @@ const std = @import("std"); -const String = []const u8; -const LiteralString = [:0]const u8; +const String = @import("base.zig").String; +const LiteralString = @import("base.zig").LiteralString; const OpenType = enum { file, fileCreate, dir, dirCreate }; fn OpenFlags(openType: OpenType) type { @@ -50,11 +50,11 @@ fn OpenFn(openType: OpenType, lazy: bool, flags: OpenFlags(openType)) type { }, else => {}, } - if (!lazy) _ = self.unlazy() catch return null; + if (!lazy) _ = self.unlazy(a_maybe) catch return null; return self; } - pub fn unlazy(self: *Self) !OpenValue(openType) { + pub fn unlazy(self: *Self, _: ?std.mem.Allocator) !OpenValue(openType) { if (!self.@".is_inited") { self.v = switch (openType) { .file => try std.fs.cwd().openFile(self.s, flags), diff --git a/src/type/read.zig b/src/type/read.zig new file mode 100644 index 0000000..92d80b4 --- /dev/null +++ b/src/type/read.zig @@ -0,0 +1,53 @@ +const std = @import("std"); + +const String = @import("base.zig").String; +const LiteralString = @import("base.zig").LiteralString; + +fn ReadFn(lazy: bool) type { + return struct { + const Self = @This(); + v: String = undefined, + s: String = undefined, + @".is_inited": bool = false, + pub fn parse(s: String, a_maybe: ?std.mem.Allocator) ?Self { + var self: Self = .{}; + + self.s = blk: { + const s_alloc = a_maybe.?.alloc(u8, s.len) catch return null; + @memcpy(s_alloc, s); + break :blk s_alloc; + }; + + if (!lazy) _ = self.unlazy(a_maybe) catch return null; + + return self; + } + pub fn unlazy(self: *Self, a_maybe: ?std.mem.Allocator) !String { + if (!self.@".is_inited") { + var fp = if (std.mem.eql(u8, self.s, "-")) std.io.getStdIn() else try std.fs.cwd().openFile(self.s, .{}); + defer fp.close(); + self.v = try fp.readToEndAlloc(a_maybe.?, 4 << 10); + self.@".is_inited" = true; + } + return self.v; + } + pub fn destroy(self: *Self, a_maybe: ?std.mem.Allocator) void { + if (self.@".is_inited") a_maybe.?.free(self.v); + a_maybe.?.free(self.s); + } + pub fn format(self: Self, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) @TypeOf(writer).Error!void { + try writer.print("Read({s})", .{self.s}); + } + }; +} + +pub const Read = struct { + pub fn f() type { + return ReadFn(false); + } +}.f; +pub const ReadLazy = struct { + pub fn f() type { + return ReadFn(true); + } +}.f; diff --git a/src/type/root.zig b/src/type/root.zig index 81b2f04..cef47df 100644 --- a/src/type/root.zig +++ b/src/type/root.zig @@ -8,8 +8,9 @@ //! const ... = ztype.zzz; //! ``` -pub const String = []const u8; -pub const LiteralString = [:0]const u8; +const base = @import("base.zig"); +pub const String = base.String; +pub const LiteralString = base.LiteralString; pub const checker = @import("checker.zig"); @@ -17,6 +18,10 @@ const open = @import("open.zig"); pub const Open = open.Open; pub const OpenLazy = open.OpenLazy; +const read = @import("read.zig"); +pub const Read = read.Read; +pub const ReadLazy = read.ReadLazy; + test { @import("std").testing.refAllDecls(@This()); }