Rename a bunch of things everywhere to make them more consistent.
`snake_case` for variables, `camelCase` for functions, `PascalCase` for classes :3
This commit is contained in:
parent
0ca0f77e04
commit
50d8cc92bd
6 changed files with 140 additions and 85 deletions
|
|
@ -2,7 +2,7 @@ const std = @import("std");
|
|||
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const inDebugMode = builtin.mode == .Debug;
|
||||
const DEBUG_MODE = builtin.mode == .Debug;
|
||||
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
|
|
@ -17,21 +17,21 @@ const log = std.log.scoped(.args);
|
|||
pub const Extra = union(enum(u2)) {
|
||||
Positional: struct {
|
||||
about: ?[]const u8 = null,
|
||||
typeHint: ?[]const u8 = null,
|
||||
type_hint: ?[]const u8 = null,
|
||||
},
|
||||
Remainder,
|
||||
Flag: struct {
|
||||
name: []const u8,
|
||||
short: ?[]const u8 = null,
|
||||
about: ?[]const u8 = null,
|
||||
typeHint: ?[]const u8 = null,
|
||||
type_hint: ?[]const u8 = null,
|
||||
toggle: bool = false,
|
||||
takesValue: bool = false,
|
||||
takes_value: bool = false,
|
||||
/// Ensures that if the flag is present, the parser will not continue parsing.
|
||||
///
|
||||
/// Warning: this is a dangerous option, as all subsequent fields will be ignored even if they have values.
|
||||
/// Only use this for flags like `--help` or `--version` or similar.
|
||||
shortCircuit: bool = false,
|
||||
short_circuit: bool = false,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -167,12 +167,12 @@ fn initFromParsed(comptime T: type, allocator: Allocator, flags: []Arg) !T {
|
|||
}
|
||||
|
||||
const fie = &@field(result, field.name);
|
||||
const fieldType = @typeInfo(@TypeOf(fie.*.value));
|
||||
const field_type = @typeInfo(@TypeOf(fie.*.value));
|
||||
const extra: Extra = fie.*.extra;
|
||||
|
||||
switch (extra) {
|
||||
.Flag => |f| {
|
||||
if (!(f.takesValue or f.toggle)) {
|
||||
if (!(f.takes_value or f.toggle)) {
|
||||
log.err("flag `{s}` must be a toggle or take a value, but it was neither", .{f.name});
|
||||
unreachable;
|
||||
}
|
||||
|
|
@ -185,7 +185,7 @@ fn initFromParsed(comptime T: type, allocator: Allocator, flags: []Arg) !T {
|
|||
if (@TypeOf(fie.*.value) == bool) {
|
||||
fie.*.value = true;
|
||||
|
||||
if (f.shortCircuit) {
|
||||
if (f.short_circuit) {
|
||||
return result;
|
||||
}
|
||||
comptime continue;
|
||||
|
|
@ -198,12 +198,12 @@ fn initFromParsed(comptime T: type, allocator: Allocator, flags: []Arg) !T {
|
|||
}
|
||||
}
|
||||
|
||||
if (f.takesValue) {
|
||||
if (f.takes_value) {
|
||||
if (flag.*.Flag.value) |value| {
|
||||
if (@TypeOf(fie.*.value) == []const u8) {
|
||||
fie.*.value = try result.allocator.dupe(u8, value);
|
||||
|
||||
if (f.shortCircuit) {
|
||||
if (f.short_circuit) {
|
||||
return result;
|
||||
}
|
||||
comptime continue;
|
||||
|
|
@ -219,7 +219,7 @@ fn initFromParsed(comptime T: type, allocator: Allocator, flags: []Arg) !T {
|
|||
return error.InvalidFlag;
|
||||
};
|
||||
|
||||
if (f.shortCircuit) {
|
||||
if (f.short_circuit) {
|
||||
return result;
|
||||
}
|
||||
comptime continue;
|
||||
|
|
@ -241,7 +241,7 @@ fn initFromParsed(comptime T: type, allocator: Allocator, flags: []Arg) !T {
|
|||
return error.InvalidFlag;
|
||||
}
|
||||
|
||||
switch (fieldType) {
|
||||
switch (field_type) {
|
||||
.optional => |_| {
|
||||
log.debug("flag `{s}` is optional, and we couldn't find a value for it, so leaving as default value", .{f.name});
|
||||
comptime continue;
|
||||
|
|
@ -266,7 +266,7 @@ fn initFromParsed(comptime T: type, allocator: Allocator, flags: []Arg) !T {
|
|||
return error.NoValueForFlag;
|
||||
}
|
||||
|
||||
if (inDebugMode) {
|
||||
if (DEBUG_MODE) {
|
||||
log.warn("flag `{s}` expected a value, but none was provided", .{f.name});
|
||||
log.warn("expected type: {s}", .{niceTypeName(@TypeOf(fie.*.value))});
|
||||
} else {
|
||||
|
|
@ -355,7 +355,7 @@ fn initFromParsed(comptime T: type, allocator: Allocator, flags: []Arg) !T {
|
|||
return error.InvalidPositional;
|
||||
}
|
||||
} else {
|
||||
switch (fieldType) {
|
||||
switch (field_type) {
|
||||
.optional => {
|
||||
if (!builtin.is_test) {
|
||||
log.warn("could not find positional argument for `{s}`, using default value", .{field.name});
|
||||
|
|
@ -371,9 +371,6 @@ fn initFromParsed(comptime T: type, allocator: Allocator, flags: []Arg) !T {
|
|||
return error.NoArgumentFound;
|
||||
}
|
||||
|
||||
log.err("could not find positional argument for `{s}`", .{field.name});
|
||||
log.warn("hint: expected type: {s}", .{niceTypeName(@TypeOf(fie.*.value))});
|
||||
log.warn("hint: try `<value>`", .{});
|
||||
return error.NoArgumentFound;
|
||||
}
|
||||
},
|
||||
|
|
@ -396,7 +393,7 @@ test "parse args" {
|
|||
.extra = Extra{
|
||||
.Flag = .{
|
||||
.name = "flag",
|
||||
.takesValue = true,
|
||||
.takes_value = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -448,7 +445,7 @@ test "missing flag" {
|
|||
.extra = Extra{
|
||||
.Flag = .{
|
||||
.name = "flag",
|
||||
.takesValue = true,
|
||||
.takes_value = true,
|
||||
},
|
||||
},
|
||||
.parse = parsers.boolean,
|
||||
|
|
@ -551,7 +548,7 @@ test "positional has default value so we get a free pass" {
|
|||
.extra = .{
|
||||
.Positional = .{},
|
||||
},
|
||||
.parse = parsers.numNullable(u8),
|
||||
.parse = parsers.num_nullable(u8),
|
||||
},
|
||||
|
||||
fn deinit(self: *@This()) void {
|
||||
|
|
@ -598,7 +595,7 @@ test "parse fn (positional)" {
|
|||
.extra = Extra{
|
||||
.Positional = .{},
|
||||
},
|
||||
.parse = parsers.enumLiteral(DemoEnum),
|
||||
.parse = parsers.enum_literal(DemoEnum),
|
||||
},
|
||||
|
||||
fn deinit(self: *@This()) void {
|
||||
|
|
@ -634,7 +631,7 @@ test "parse fn (flag)" {
|
|||
.extra = Extra{
|
||||
.Flag = .{
|
||||
.name = "number",
|
||||
.takesValue = true,
|
||||
.takes_value = true,
|
||||
},
|
||||
},
|
||||
.parse = parsers.num(u16),
|
||||
|
|
@ -654,10 +651,10 @@ test "parse fn (flag)" {
|
|||
.extra = Extra{
|
||||
.Flag = .{
|
||||
.name = "enumeration",
|
||||
.takesValue = true,
|
||||
.takes_value = true,
|
||||
},
|
||||
},
|
||||
.parse = parsers.enumLiteral(DemoEnum),
|
||||
.parse = parsers.enum_literal(DemoEnum),
|
||||
},
|
||||
|
||||
fn deinit(self: *@This()) void {
|
||||
|
|
@ -769,7 +766,7 @@ test "sub command from remainder" {
|
|||
.extra = .{
|
||||
.Flag = .{
|
||||
.name = "flag",
|
||||
.takesValue = true,
|
||||
.takes_value = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ const std = @import("std");
|
|||
|
||||
const log = std.log.scoped(.help);
|
||||
|
||||
const argLib = @import("args.zig");
|
||||
const Marker = argLib.Marker;
|
||||
const Extra = argLib.Extra;
|
||||
const arg_lib = @import("args.zig");
|
||||
const Marker = arg_lib.Marker;
|
||||
const Extra = arg_lib.Extra;
|
||||
|
||||
const niceTypeName = @import("../util/utils.zig").niceTypeName;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ pub fn enumLiteral(comptime T: type) *const fn (value: []const u8) anyerror!T {
|
|||
const log = std.log.scoped(.args);
|
||||
|
||||
fn parseEnumFromStr(comptime T: type, str: []const u8) !T {
|
||||
const heapAllocator = std.heap.page_allocator;
|
||||
const lower = try std.ascii.allocLowerString(heapAllocator, str);
|
||||
defer heapAllocator.free(lower);
|
||||
const heap_allocator = std.heap.page_allocator;
|
||||
const lower = try std.ascii.allocLowerString(heap_allocator, str);
|
||||
defer heap_allocator.free(lower);
|
||||
const info = @typeInfo(T);
|
||||
|
||||
comptime {
|
||||
|
|
@ -26,9 +26,9 @@ fn parseEnumFromStr(comptime T: type, str: []const u8) !T {
|
|||
}
|
||||
|
||||
inline for (info.@"enum".fields) |field| {
|
||||
const lowerFieldName = try std.ascii.allocLowerString(heapAllocator, field.name);
|
||||
defer heapAllocator.free(lowerFieldName);
|
||||
if (std.mem.eql(u8, lowerFieldName, lower)) {
|
||||
const lower_field_name = try std.ascii.allocLowerString(heap_allocator, field.name);
|
||||
defer heap_allocator.free(lower_field_name);
|
||||
if (std.mem.eql(u8, lower_field_name, lower)) {
|
||||
return @enumFromInt(field.value);
|
||||
}
|
||||
}
|
||||
|
|
@ -42,9 +42,9 @@ fn parseEnumFromStr(comptime T: type, str: []const u8) !T {
|
|||
log.warn("hint: try one of the following:", .{});
|
||||
|
||||
inline for (info.@"enum".fields) |field| {
|
||||
const lowerFieldName = try std.ascii.allocLowerString(heapAllocator, field.name);
|
||||
defer heapAllocator.free(lowerFieldName);
|
||||
log.warn("- {s}", .{lowerFieldName});
|
||||
const lower_field_name = try std.ascii.allocLowerString(heap_allocator, field.name);
|
||||
defer heap_allocator.free(lower_field_name);
|
||||
log.warn("- {s}", .{lower_field_name});
|
||||
}
|
||||
|
||||
return error.CouldNotParse;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ pub fn ParseSignature(comptime T: type) type {
|
|||
}
|
||||
|
||||
pub const num = @import("./num.zig").num;
|
||||
pub const numNullable = @import("./numNullable.zig").numNullable;
|
||||
pub const num_nullable = @import("./numNullable.zig").numNullable;
|
||||
pub const boolean = @import("./boolean.zig").boolean;
|
||||
pub const enumLiteral = @import("./enumLiteral.zig").enumLiteral;
|
||||
pub const enum_literal = @import("./enumLiteral.zig").enumLiteral;
|
||||
|
||||
test "valid parser signatures" {
|
||||
const t = std.testing;
|
||||
|
|
@ -19,7 +19,7 @@ test "valid parser signatures" {
|
|||
try t.expectEqual(ParseSignature(bool), @TypeOf(&boolean));
|
||||
|
||||
const Enum = enum { Value, Other };
|
||||
try t.expectEqual(ParseSignature(Enum), @TypeOf(enumLiteral(Enum)));
|
||||
try t.expectEqual(ParseSignature(Enum), @TypeOf(enum_literal(Enum)));
|
||||
}
|
||||
|
||||
comptime {
|
||||
|
|
@ -27,7 +27,8 @@ comptime {
|
|||
|
||||
if (builtin.is_test) {
|
||||
std.mem.doNotOptimizeAway(num);
|
||||
std.mem.doNotOptimizeAway(num_nullable);
|
||||
std.mem.doNotOptimizeAway(boolean);
|
||||
std.mem.doNotOptimizeAway(enumLiteral);
|
||||
std.mem.doNotOptimizeAway(enum_literal);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ pub const Color = enum {
|
|||
|
||||
pub const ScopeModifier = struct {
|
||||
scope: SmartString,
|
||||
prefix_match: bool = false,
|
||||
color: ?Color = .default,
|
||||
bright: bool = false,
|
||||
rename: ?SmartString = null,
|
||||
};
|
||||
|
||||
|
|
@ -31,13 +31,13 @@ const Allocator = std.mem.Allocator;
|
|||
const Globals = struct {
|
||||
allocator: Allocator,
|
||||
|
||||
enableFileOutput: bool = false,
|
||||
outputFile: ?std.fs.File = null,
|
||||
enable_file_output: bool = false,
|
||||
output_file: ?std.fs.File = null,
|
||||
|
||||
additionalScopes: std.ArrayList(ScopeModifier),
|
||||
additional_scopes: std.ArrayList(ScopeModifier),
|
||||
|
||||
fn initOrGetFile(self: *Globals) !std.fs.File {
|
||||
if (self.outputFile) |file| {
|
||||
if (self.output_file) |file| {
|
||||
return file;
|
||||
} else {
|
||||
return error.NoFileSet;
|
||||
|
|
@ -48,26 +48,26 @@ const Globals = struct {
|
|||
return .{
|
||||
.allocator = allocator,
|
||||
|
||||
.enableFileOutput = false,
|
||||
.outputFile = null,
|
||||
.enable_file_output = false,
|
||||
.output_file = null,
|
||||
|
||||
.additionalScopes = std.ArrayList(ScopeModifier).init(allocator),
|
||||
.additional_scopes = std.ArrayList(ScopeModifier).init(allocator),
|
||||
};
|
||||
}
|
||||
|
||||
fn deinit(self: *Globals) void {
|
||||
if (self.outputFile) |file| {
|
||||
if (self.output_file) |file| {
|
||||
file.close();
|
||||
}
|
||||
|
||||
for (self.additionalScopes.items) |*modifier| {
|
||||
for (self.additional_scopes.items) |*modifier| {
|
||||
if (modifier.*.rename) |*value| {
|
||||
value.deinit();
|
||||
}
|
||||
|
||||
modifier.*.scope.deinit();
|
||||
}
|
||||
self.additionalScopes.deinit();
|
||||
self.additional_scopes.deinit();
|
||||
|
||||
self.* = undefined;
|
||||
}
|
||||
|
|
@ -76,9 +76,9 @@ const Globals = struct {
|
|||
var core: ?Globals = null;
|
||||
|
||||
pub const config = struct {
|
||||
pub fn enableFileOutput(value: bool) void {
|
||||
pub fn setFileOutput(value: bool) void {
|
||||
if (core) |*globals| {
|
||||
globals.enableFileOutput = value;
|
||||
globals.enable_file_output = value;
|
||||
} else {
|
||||
unreachable; // logging is not initialized
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ pub const config = struct {
|
|||
|
||||
pub fn isFileOutput() bool {
|
||||
if (core) |*globals| {
|
||||
return globals.enableFileOutput;
|
||||
return globals.enable_file_output;
|
||||
} else {
|
||||
unreachable; // logging is not initialized
|
||||
}
|
||||
|
|
@ -94,7 +94,7 @@ pub const config = struct {
|
|||
|
||||
pub fn setOutputFile(file: std.fs.File) !void {
|
||||
if (core) |*globals| {
|
||||
globals.outputFile = file;
|
||||
globals.output_file = file;
|
||||
} else {
|
||||
unreachable; // logging is not initialized
|
||||
}
|
||||
|
|
@ -102,7 +102,7 @@ pub const config = struct {
|
|||
|
||||
pub fn getOutputFile() ?*const std.fs.File {
|
||||
if (core) |*globals| {
|
||||
return &globals.outputFile;
|
||||
return &globals.output_file;
|
||||
} else {
|
||||
unreachable; // logging is not initialized
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ pub const config = struct {
|
|||
|
||||
pub fn addScope(modifier: ScopeModifier) !void {
|
||||
if (core) |*globals| {
|
||||
try globals.additionalScopes.append(modifier);
|
||||
try globals.additional_scopes.append(modifier);
|
||||
} else {
|
||||
unreachable; // logging is not initialized
|
||||
}
|
||||
|
|
@ -146,6 +146,57 @@ fn get() *Globals {
|
|||
unreachable; // logging is not initialized
|
||||
}
|
||||
|
||||
fn isMatch(name: []const u8, modifier: *const ScopeModifier) bool {
|
||||
if (modifier.prefix_match) {
|
||||
return std.mem.startsWith(u8, name, modifier.scope.data);
|
||||
}
|
||||
|
||||
return std.mem.eql(u8, name, modifier.scope.data);
|
||||
}
|
||||
|
||||
fn prep(name: []const u8, modifier: ?*const ScopeModifier, allocator: Allocator) ![]const u8 {
|
||||
if (!std.mem.containsAtLeastScalar(u8, name, 1, '_'))
|
||||
return name;
|
||||
|
||||
var c = cham.initRuntime(.{
|
||||
.allocator = allocator,
|
||||
});
|
||||
|
||||
var chunks = std.mem.tokenizeScalar(u8, name, '_');
|
||||
|
||||
var output = std.ArrayList(u8).init(allocator);
|
||||
|
||||
var isFirst = true;
|
||||
while (chunks.next()) |chunk| {
|
||||
if (!isFirst) {
|
||||
_ = try output.writer().write("::");
|
||||
} else {
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
if (modifier) |mod| {
|
||||
if (mod.color) |color| {
|
||||
_ = switch (color) {
|
||||
.default => try output.writer().write(chunk),
|
||||
.blue => try output.writer().write(try c.blue().fmt("{s}", .{chunk})),
|
||||
.green => try output.writer().write(try c.green().fmt("{s}", .{chunk})),
|
||||
.red => try output.writer().write(try c.red().fmt("{s}", .{chunk})),
|
||||
.white => try output.writer().write(try c.white().fmt("{s}", .{chunk})),
|
||||
.yellow => try output.writer().write(try c.yellow().fmt("{s}", .{chunk})),
|
||||
.magenta => try output.writer().write(try c.magenta().fmt("{s}", .{chunk})),
|
||||
.cyan => try output.writer().write(try c.cyan().fmt("{s}", .{chunk})),
|
||||
};
|
||||
} else {
|
||||
_ = try output.writer().write(chunk);
|
||||
}
|
||||
} else {
|
||||
_ = try output.writer().write(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
return try output.toOwnedSlice();
|
||||
}
|
||||
|
||||
fn logFnImpl(comptime level: Level, comptime scope: Scope, comptime format: []const u8, args: anytype) !void {
|
||||
const globals = get();
|
||||
var arena = std.heap.ArenaAllocator.init(globals.allocator);
|
||||
|
|
@ -167,13 +218,13 @@ fn logFnImpl(comptime level: Level, comptime scope: Scope, comptime format: []co
|
|||
},
|
||||
|
||||
else => {
|
||||
for (globals.additionalScopes.items) |modifier| {
|
||||
if (std.mem.eql(u8, modifier.scope.data, @tagName(scope))) {
|
||||
for (globals.additional_scopes.items) |modifier| {
|
||||
if (isMatch(@tagName(scope), &modifier)) {
|
||||
const text = blk: {
|
||||
if (modifier.rename) |rename| {
|
||||
break :blk rename.data;
|
||||
} else {
|
||||
break :blk @tagName(scope);
|
||||
break :blk try prep(@tagName(scope), &modifier, arena.allocator());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -193,7 +244,7 @@ fn logFnImpl(comptime level: Level, comptime scope: Scope, comptime format: []co
|
|||
}
|
||||
}
|
||||
} else {
|
||||
break :scopeTextBlk @tagName(scope);
|
||||
break :scopeTextBlk try prep(@tagName(scope), null, arena.allocator());
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
@ -215,7 +266,7 @@ fn logFnImpl(comptime level: Level, comptime scope: Scope, comptime format: []co
|
|||
|
||||
const message = try std.fmt.allocPrint(arena.allocator(), format, args);
|
||||
|
||||
if (globals.enableFileOutput and globals.outputFile != null) {
|
||||
if (globals.enable_file_output and globals.output_file != null) {
|
||||
var file = try globals.initOrGetFile();
|
||||
var writer = file.writer().any();
|
||||
|
||||
|
|
@ -238,17 +289,23 @@ test "logFn works" {
|
|||
defer deinit();
|
||||
|
||||
try config.addScope(.{
|
||||
.scope = SmartString.constant("someScope"),
|
||||
.rename = SmartString.constant("some rename"),
|
||||
.scope = .constant("some_scope"),
|
||||
.rename = .constant("some rename"),
|
||||
.color = .green,
|
||||
});
|
||||
try config.addScope(.{
|
||||
.scope = SmartString.constant("other"),
|
||||
.rename = SmartString.constant("other rename"),
|
||||
.scope = .constant("other"),
|
||||
.rename = .constant("other rename"),
|
||||
.color = .blue,
|
||||
});
|
||||
try config.addScope(.{
|
||||
.scope = .constant("test"),
|
||||
.prefix_match = true,
|
||||
.color = .yellow,
|
||||
});
|
||||
|
||||
try logFnImpl(.err, .default, "hello world", .{});
|
||||
try logFnImpl(.info, .someScope, "hello world", .{});
|
||||
try logFnImpl(.info, .some_scope, "hello world", .{});
|
||||
try logFnImpl(.warn, .other, "hello world", .{});
|
||||
try logFnImpl(.err, .test_scope, "hello world", .{});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,20 +205,20 @@ const t = std.testing;
|
|||
test "the different kinds work" {
|
||||
const a = t.allocator;
|
||||
|
||||
var strOne = try SmartString.alloc("hello, world", a);
|
||||
defer strOne.deinit();
|
||||
var str_one = try SmartString.alloc("hello, world", a);
|
||||
defer str_one.deinit();
|
||||
|
||||
try t.expectEqualStrings("hello, world", strOne.data);
|
||||
try t.expectEqual(AllocKind{ .Allocated = a }, strOne.kind);
|
||||
try t.expectEqualStrings("hello, world", str_one.data);
|
||||
try t.expectEqual(AllocKind{ .Allocated = a }, str_one.kind);
|
||||
|
||||
var strTwo = SmartString.constant("hello, world");
|
||||
defer strTwo.deinit();
|
||||
var str_two = SmartString.constant("hello, world");
|
||||
defer str_two.deinit();
|
||||
|
||||
try t.expectEqualStrings("hello, world", strTwo.data);
|
||||
try t.expectEqual(AllocKind{ .Constant = {} }, strTwo.kind);
|
||||
try t.expectEqualStrings("hello, world", str_two.data);
|
||||
try t.expectEqual(AllocKind{ .Constant = {} }, str_two.kind);
|
||||
|
||||
try t.expectEqualStrings(strOne.data, strTwo.data);
|
||||
try t.expect(!strOne.kind.eql(strTwo.kind));
|
||||
try t.expectEqualStrings(str_one.data, str_two.data);
|
||||
try t.expect(!str_one.kind.eql(str_two.kind));
|
||||
}
|
||||
|
||||
test "allocKind eql works" {
|
||||
|
|
@ -239,14 +239,14 @@ test "allocKind eql works" {
|
|||
test "clone works" {
|
||||
const a = t.allocator;
|
||||
|
||||
var strOne = try SmartString.alloc("hello, world", a);
|
||||
defer strOne.deinit();
|
||||
var str_one = try SmartString.alloc("hello, world", a);
|
||||
defer str_one.deinit();
|
||||
|
||||
var strTwo = try strOne.clone();
|
||||
defer strTwo.deinit();
|
||||
var str_two = try str_one.clone();
|
||||
defer str_two.deinit();
|
||||
|
||||
try t.expectEqualStrings("hello, world", strOne.data);
|
||||
try t.expectEqualStrings("hello, world", strTwo.data);
|
||||
try t.expectEqualStrings("hello, world", str_one.data);
|
||||
try t.expectEqualStrings("hello, world", str_two.data);
|
||||
|
||||
try t.expect(strOne.kind.eql(strTwo.kind));
|
||||
try t.expect(str_one.kind.eql(str_two.kind));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue