Text string - chung-leong/zigar GitHub Wiki
There is no specialized string type in the Zig language. Text strings are usually stored in []u8
using UTF-8 encoding. Since the same data type is used to store raw binary data, the Zigar runtime
does not automatically interpret []u8
as text. You have to instead access a
special property to obtain a string:
This is not a huge burden usually. It does prevent valueOf() from returning sensible results in a situation like the following:
pub const Avenger = struct {
real_name: []const u8,
superhero_name: []const u8,
age: u32,
};
pub const spiderman: Avenger = .{
.real_name = "Peter Parker",
.superhero_name = "Spiderman",
.age = 17,
};
import { spiderman } from './string-example-1.zig';
console.log(spiderman.valueOf());
{
real_name: [
80, 101, 116, 101, 114,
32, 80, 97, 114, 107,
101, 114
],
superhero_name: [
83, 112, 105, 100,
101, 114, 109, 97,
110
],
age: 17
}
This also affects the output from JSON.stringify()
. To deal with this rather annoying issue,
Zigar gives you a way of flagging particular fields as being strings. It involves a namespace with
a special name:
pub const Avenger = struct {
real_name: []const u8,
superhero_name: []const u8,
age: u32,
};
pub const spiderman: Avenger = .{
.real_name = "Peter Parker",
.superhero_name = "Spiderman",
.age = 17,
};
pub const @"meta(zigar)" = struct {
pub fn isFieldString(comptime T: type, comptime field_name: []const u8) bool {
_ = field_name;
return switch (T) {
Avenger => true,
else => false,
};
}
};
import { spiderman } from './string-example-2.zig';
console.log(spiderman.real_name);
console.log(spiderman.superhero_name);
console.log(spiderman.valueOf());
Peter Parker
Spiderman
{ real_name: 'Peter Parker', superhero_name: 'Spiderman', age: 17 }
The namespace @"meta(zigar)"
must be declared in the root module. A declaration by that name in
an imported module would have zero effect. Zigar wouldn't even have access to it.
You can also make the return value of a function a string:
const std = @import("std");
pub const allocUpperString = std.ascii.allocUpperString;
pub const @"meta(zigar)" = struct {
pub fn isRetvalString(comptime func: anytype) bool {
const list = .{
std.ascii.allocUpperString,
};
return inline for (list) |f| {
if (@TypeOf(func) == @TypeOf(f) and func == f) break true;
} else false;
}
};
import { allocUpperString } from './string-example-3.zig';
console.log(allocUpperString('hello world'));
HELLO WORLD
Note the type comparison, which keeps a mismatched function type error from occurring.
Arguments to callback functions can also be flagged:
pub const Callback = fn ([]const u8) error{Unexpected}!void;
pub fn call(cb: *const Callback) !void {
try cb("Hello world!");
}
pub const @"meta(zigar)" = struct {
pub fn isArgumentString(comptime FT: type, comptime arg_index: usize) bool {
_ = arg_index;
return switch (FT) {
Callback => true,
else => false,
};
}
};
import { call } from './string-example-4.zig';
call(s => console.log(s));
Hello world!