Seperated Structs and Tables
This allows multiple tables to use the exsact same struct, it also allows substructs to be used multiple times.
This commit is contained in:
parent
bb444a9755
commit
2331a29358
4 changed files with 136 additions and 102 deletions
|
|
@ -7,7 +7,8 @@ pub export fn spacetime_includes() void {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const moduleTablesDef = .{
|
pub const moduleTablesDef = .{
|
||||||
.person = Person,
|
.person = spacetime.Table(.{.name = "person", .layout = Person}),
|
||||||
|
.person2 = spacetime.Table(.{.name = "person2", .layout = Person}),
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const moduleReducersDef = .{
|
pub const moduleReducersDef = .{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const utils = @import("spacetime/utils.zig");
|
||||||
|
|
||||||
pub const st_types = @import("spacetime/types.zig");
|
pub const st_types = @import("spacetime/types.zig");
|
||||||
pub const serializer = @import("spacetime/serializer.zig");
|
pub const serializer = @import("spacetime/serializer.zig");
|
||||||
|
|
@ -146,11 +147,14 @@ fn spacetimeType2ZigType(t: AlgebraicType) type {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StructFieldImpl = struct {
|
||||||
|
name: []const u8,
|
||||||
|
type: AlgebraicType,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn Struct(comptime decl: StructDecl) type {
|
pub fn Struct(comptime decl: StructDecl) type {
|
||||||
const @"spacetime_10.0__struct_" = struct {
|
const @"spacetime_10.0__struct_" = struct {
|
||||||
name: ?[]const u8 = decl.name,
|
name: []const u8 = decl.name,
|
||||||
table_type: TableType = .User,
|
|
||||||
table_access: TableAccess = .Private,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var zigStructMembers: []const std.builtin.Type.StructField = &[_]std.builtin.Type.StructField{
|
var zigStructMembers: []const std.builtin.Type.StructField = &[_]std.builtin.Type.StructField{
|
||||||
|
|
@ -185,16 +189,21 @@ pub fn Struct(comptime decl: StructDecl) type {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn Table(comptime decl: type) type {
|
pub const TableDecl = struct {
|
||||||
// const @"spacetime_10.0__table_" = struct {
|
name: []const u8,
|
||||||
// name: []const u8,
|
layout: type,
|
||||||
// table_type: TableType = .User,
|
};
|
||||||
// table_access: TableAccess = .Private,
|
|
||||||
// type: decl = std.mem.zeroes(decl),
|
|
||||||
// };
|
|
||||||
|
|
||||||
// return @"spacetime_10.0__table_";
|
pub fn Table(comptime decl: TableDecl) type {
|
||||||
//}
|
const @"spacetime_10.0__table_" = struct {
|
||||||
|
name: []const u8 = decl.name,
|
||||||
|
table_type: TableType = .User,
|
||||||
|
table_access: TableAccess = .Private,
|
||||||
|
layout: @TypeOf(decl.layout) = decl.layout,
|
||||||
|
};
|
||||||
|
|
||||||
|
return @"spacetime_10.0__table_";
|
||||||
|
}
|
||||||
|
|
||||||
pub fn readArg(allocator: std.mem.Allocator, args: BytesSource, comptime t: AlgebraicType) !spacetimeType2ZigType(t) {
|
pub fn readArg(allocator: std.mem.Allocator, args: BytesSource, comptime t: AlgebraicType) !spacetimeType2ZigType(t) {
|
||||||
switch(t) {
|
switch(t) {
|
||||||
|
|
@ -236,62 +245,53 @@ pub fn zigTypeToSpacetimeType(comptime param: ?type) AlgebraicType {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn buildTypeList(name: []const u8, default_values: type, raw_types: *[]const AlgebraicType, types: *[]const RawTypeDefV9) usize
|
const StructImpl = struct {
|
||||||
{
|
name: []const u8,
|
||||||
var product_elements: []const ProductTypeElement = &[_]ProductTypeElement{};
|
fields: []const StructFieldImpl,
|
||||||
|
};
|
||||||
|
|
||||||
inline for(@typeInfo(default_values).@"struct".fields, 0..) |table_field, i| {
|
pub fn addStructImpl(structImpls: *[]const StructImpl, layout: anytype) u32 {
|
||||||
if(i == 0) continue;
|
var members: []const StructFieldImpl = &[_]StructFieldImpl{};
|
||||||
|
|
||||||
|
const fields = std.meta.fields(layout);
|
||||||
if(@typeInfo(table_field.type) == .@"struct" and std.meta.fieldIndex(table_field.type, MagicStruct) != null) {
|
const name = utils.getMemberDefaultValue(fields[0].type, "name");
|
||||||
|
|
||||||
const table = std.meta.fields(table_field.type)[std.meta.fieldIndex(table_field.type, MagicStruct).?];
|
//FIXME: Search for existing structImpl of provided layout. I think the current might work, but I don't trust it.
|
||||||
const subname = @as(*table.type, @constCast(@alignCast(@ptrCast(table.default_value)))).*.name.?;
|
inline for(structImpls.*, 0..) |structImpl, i| {
|
||||||
//_ = subname;
|
if(std.mem.eql(u8, structImpl.name, name)) {
|
||||||
//@compileLog(table_field.type);
|
return i;
|
||||||
const id = buildTypeList(subname, table_field.type, raw_types, types);
|
}
|
||||||
product_elements = product_elements ++ &[_]ProductTypeElement{
|
}
|
||||||
|
|
||||||
|
inline for(fields[1..]) |field| {
|
||||||
|
if(@typeInfo(field.type) == .@"struct") {
|
||||||
|
members = members ++ &[_]StructFieldImpl{
|
||||||
.{
|
.{
|
||||||
.name = table_field.name,
|
.name = field.name,
|
||||||
.algebraic_type = .{
|
.type = .{
|
||||||
.Ref = .{
|
.Ref = .{
|
||||||
.inner = id,
|
.inner = addStructImpl(structImpls, field.type),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
product_elements = product_elements ++ &[_]ProductTypeElement{
|
members = members ++ &[_]StructFieldImpl{
|
||||||
.{
|
.{
|
||||||
.name = table_field.name,
|
.name = field.name,
|
||||||
.algebraic_type = zigTypeToSpacetimeType(table_field.type)
|
.type = zigTypeToSpacetimeType(field.type),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
members = members ++ &[_]StructFieldImpl{};
|
||||||
}
|
}
|
||||||
|
structImpls.* = structImpls.* ++ &[_]StructImpl{
|
||||||
raw_types.* = raw_types.* ++ &[_]AlgebraicType{
|
|
||||||
.{
|
.{
|
||||||
.Product = .{
|
.name = name,
|
||||||
.elements = product_elements,
|
.fields = members,
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
types.* = types.* ++ &[_]RawTypeDefV9{
|
return structImpls.len - 1;
|
||||||
.{
|
|
||||||
.name = .{
|
|
||||||
.scope = &[_][]u8{},
|
|
||||||
.name = name
|
|
||||||
},
|
|
||||||
.ty = .{ .inner = raw_types.len-1, },
|
|
||||||
.custom_ordering = true,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return types.len-1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile(comptime moduleTables : anytype, comptime moduleReducers : anytype) !RawModuleDefV9 {
|
pub fn compile(comptime moduleTables : anytype, comptime moduleReducers : anytype) !RawModuleDefV9 {
|
||||||
|
|
@ -304,25 +304,16 @@ pub fn compile(comptime moduleTables : anytype, comptime moduleReducers : anytyp
|
||||||
var raw_types: []const AlgebraicType = &[_]AlgebraicType{};
|
var raw_types: []const AlgebraicType = &[_]AlgebraicType{};
|
||||||
var types: []const RawTypeDefV9 = &[_]RawTypeDefV9{};
|
var types: []const RawTypeDefV9 = &[_]RawTypeDefV9{};
|
||||||
|
|
||||||
|
var structDecls: []const StructImpl = &[_]StructImpl{};
|
||||||
|
|
||||||
inline for(std.meta.fields(@TypeOf(moduleTables))) |field| {
|
inline for(std.meta.fields(@TypeOf(moduleTables))) |field| {
|
||||||
//const struct_decl = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*;
|
const table: @as(*const field.type, @alignCast(@ptrCast(field.default_value))).* = .{};
|
||||||
//@compileLog(@TypeOf(struct_decl.type));
|
const name: []const u8 = table.name;
|
||||||
const default_values = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*;
|
const table_type: TableType = table.table_type;
|
||||||
const structInfo = blk: {
|
const table_access: TableAccess = table.table_access;
|
||||||
for(@typeInfo(default_values).@"struct".fields) |structInfoField| {
|
|
||||||
if(std.mem.eql(u8, structInfoField.name, MagicStruct)) {
|
|
||||||
break :blk structInfoField.type{};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const product_type_ref: AlgebraicTypeRef = AlgebraicTypeRef{
|
const product_type_ref: AlgebraicTypeRef = AlgebraicTypeRef{
|
||||||
.inner = buildTypeList(field.name, default_values, &raw_types, &types),
|
.inner = addStructImpl(&structDecls, table.layout),
|
||||||
};
|
};
|
||||||
|
|
||||||
const name: []const u8 = structInfo.name.?;
|
|
||||||
const table_type: TableType = structInfo.table_type;
|
|
||||||
const table_access: TableAccess = structInfo.table_access;
|
|
||||||
tables = tables ++ &[_]RawTableDefV9{
|
tables = tables ++ &[_]RawTableDefV9{
|
||||||
.{
|
.{
|
||||||
.name = name,
|
.name = name,
|
||||||
|
|
@ -338,6 +329,39 @@ pub fn compile(comptime moduleTables : anytype, comptime moduleReducers : anytyp
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline for(structDecls) |structDecl| {
|
||||||
|
var product_elements: []const ProductTypeElement = &[_]ProductTypeElement{};
|
||||||
|
|
||||||
|
inline for(structDecl.fields) |field|
|
||||||
|
{
|
||||||
|
product_elements = product_elements ++ &[_]ProductTypeElement{
|
||||||
|
.{
|
||||||
|
.name = field.name,
|
||||||
|
.algebraic_type = field.type,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
raw_types = raw_types ++ &[_]AlgebraicType{
|
||||||
|
.{
|
||||||
|
.Product = .{
|
||||||
|
.elements = product_elements,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
types = types ++ &[_]RawTypeDefV9{
|
||||||
|
.{
|
||||||
|
.name = .{
|
||||||
|
.scope = &[_][]u8{},
|
||||||
|
.name = structDecl.name
|
||||||
|
},
|
||||||
|
.ty = .{ .inner = raw_types.len-1, },
|
||||||
|
.custom_ordering = true,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
inline for(std.meta.fields(@TypeOf(moduleReducers))) |field| {
|
inline for(std.meta.fields(@TypeOf(moduleReducers))) |field| {
|
||||||
const default_values = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*;
|
const default_values = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*;
|
||||||
const name: []const u8 = default_values.name orelse field.name;
|
const name: []const u8 = default_values.name orelse field.name;
|
||||||
|
|
@ -501,20 +525,6 @@ pub export fn __describe_module__(description: BytesSink) void {
|
||||||
write_to_sink(description, moduleDefBytes.items);
|
write_to_sink(description, moduleDefBytes.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn itoa(comptime value: anytype) [:0]const u8 {
|
|
||||||
comptime var s: []const u8 = &[_]u8{};
|
|
||||||
comptime var n = value;
|
|
||||||
if (n == 0) {
|
|
||||||
s = s ++ .{'0'};
|
|
||||||
} else {
|
|
||||||
comptime while (n != 0) {
|
|
||||||
s = s ++ .{'0' + (n % 10)};
|
|
||||||
n = n / 10;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return @ptrCast(s ++ .{0});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub export fn __call_reducer__(
|
pub export fn __call_reducer__(
|
||||||
id: usize,
|
id: usize,
|
||||||
sender_0: u64,
|
sender_0: u64,
|
||||||
|
|
@ -545,7 +555,7 @@ pub export fn __call_reducer__(
|
||||||
if( comptime std.mem.endsWith(u8, @typeName(field.type), "spacetime_10.0__reducer_")) {
|
if( comptime std.mem.endsWith(u8, @typeName(field.type), "spacetime_10.0__reducer_")) {
|
||||||
defer i += 1;
|
defer i += 1;
|
||||||
if(id == i) {
|
if(id == i) {
|
||||||
const func = std.meta.fields(field.type)[std.meta.fieldIndex(field.type, "func").?].type;
|
const func = utils.getMemberDefaultType(field.type, "func");
|
||||||
const params = @typeInfo(func).@"fn".params;
|
const params = @typeInfo(func).@"fn".params;
|
||||||
const param_names = @field(moduleReducersDef, field.name).param_names;
|
const param_names = @field(moduleReducersDef, field.name).param_names;
|
||||||
comptime var argCount = 1;
|
comptime var argCount = 1;
|
||||||
|
|
@ -566,7 +576,7 @@ pub export fn __call_reducer__(
|
||||||
.alignment = 0,
|
.alignment = 0,
|
||||||
.default_value = null,
|
.default_value = null,
|
||||||
.is_comptime = false,
|
.is_comptime = false,
|
||||||
.name = comptime itoa(argCount),
|
.name = comptime utils.itoa(argCount),
|
||||||
.type = param.type.?,
|
.type = param.type.?,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -590,7 +600,7 @@ pub export fn __call_reducer__(
|
||||||
if(args.inner != 0) {
|
if(args.inner != 0) {
|
||||||
inline for(params, 0..) |param, name| {
|
inline for(params, 0..) |param, name| {
|
||||||
comptime if(name == 0) continue;
|
comptime if(name == 0) continue;
|
||||||
@field(constructedArg, itoa(name)) = readArg(allocator, args, zigTypeToSpacetimeType(param.type.?)) catch |err2| {
|
@field(constructedArg, utils.itoa(name)) = readArg(allocator, args, zigTypeToSpacetimeType(param.type.?)) catch |err2| {
|
||||||
var buf: [512]u8 = undefined;
|
var buf: [512]u8 = undefined;
|
||||||
print(std.fmt.bufPrint(&buf, "Error: {}", .{err2}) catch "Expand Error Buffer!");
|
print(std.fmt.bufPrint(&buf, "Error: {}", .{err2}) catch "Expand Error Buffer!");
|
||||||
@panic("blah");
|
@panic("blah");
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const utils = @import("utils.zig");
|
||||||
const spacetime = @import("../spacetime.zig");
|
const spacetime = @import("../spacetime.zig");
|
||||||
const console_log = spacetime.console_log;
|
const console_log = spacetime.console_log;
|
||||||
const TableId = spacetime.TableId;
|
const TableId = spacetime.TableId;
|
||||||
|
|
@ -130,7 +131,8 @@ pub const Lifecycle = enum {
|
||||||
|
|
||||||
fn getStructSize(data: anytype) usize {
|
fn getStructSize(data: anytype) usize {
|
||||||
const struct_type = @TypeOf(data);
|
const struct_type = @TypeOf(data);
|
||||||
const @"spacetime_10.0__table_" = std.meta.fields(struct_type)[std.meta.fieldIndex(struct_type, spacetime.MagicStruct).?].type;
|
|
||||||
|
const @"spacetime_10.0__table_" = utils.getMemberDefaultType(struct_type, spacetime.MagicStruct);
|
||||||
|
|
||||||
const fields = std.meta.fields(@TypeOf(data));
|
const fields = std.meta.fields(@TypeOf(data));
|
||||||
var size: usize = 0;
|
var size: usize = 0;
|
||||||
|
|
@ -155,7 +157,6 @@ fn getStructSize(data: anytype) usize {
|
||||||
size += getStructSize(@field(data, field.name));
|
size += getStructSize(@field(data, field.name));
|
||||||
break :blk;
|
break :blk;
|
||||||
}
|
}
|
||||||
//const subname = @as(*field.type, @constCast(@alignCast(@ptrCast(field.default_value)))).*.name.?;
|
|
||||||
@compileLog(field.type);
|
@compileLog(field.type);
|
||||||
@compileError("Unsupported type in StructSerializer");
|
@compileError("Unsupported type in StructSerializer");
|
||||||
},
|
},
|
||||||
|
|
@ -167,7 +168,7 @@ fn getStructSize(data: anytype) usize {
|
||||||
|
|
||||||
fn getStructData(data: anytype, mem: []u8) []u8 {
|
fn getStructData(data: anytype, mem: []u8) []u8 {
|
||||||
const struct_type = @TypeOf(data);
|
const struct_type = @TypeOf(data);
|
||||||
const @"spacetime_10.0__table_" = std.meta.fields(struct_type)[std.meta.fieldIndex(struct_type, spacetime.MagicStruct).?].type;
|
const @"spacetime_10.0__table_" = utils.getMemberDefaultType(struct_type, spacetime.MagicStruct);
|
||||||
|
|
||||||
const fields = std.meta.fields(@TypeOf(data));
|
const fields = std.meta.fields(@TypeOf(data));
|
||||||
var offset_mem = mem;
|
var offset_mem = mem;
|
||||||
|
|
@ -220,8 +221,7 @@ pub fn StructSerializer(struct_type: type) fn(std.mem.Allocator, struct_type) st
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn StructDeserializer(struct_type: type) fn(allocator: std.mem.Allocator, *[]const u8) std.mem.Allocator.Error!*struct_type {
|
pub fn StructDeserializer(struct_type: type) fn(allocator: std.mem.Allocator, *[]const u8) std.mem.Allocator.Error!*struct_type {
|
||||||
|
const @"spacetime_10.0__table_" = utils.getMemberDefaultType(struct_type, spacetime.MagicStruct);
|
||||||
const @"spacetime_10.0__table_" = std.meta.fields(struct_type)[std.meta.fieldIndex(struct_type, spacetime.MagicStruct).?].type;
|
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
pub fn deserialize(allocator: std.mem.Allocator, data: *[]const u8) std.mem.Allocator.Error!*struct_type {
|
pub fn deserialize(allocator: std.mem.Allocator, data: *[]const u8) std.mem.Allocator.Error!*struct_type {
|
||||||
|
|
@ -265,13 +265,10 @@ pub fn StructDeserializer(struct_type: type) fn(allocator: std.mem.Allocator, *[
|
||||||
}.deserialize;
|
}.deserialize;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Table2Struct(comptime table_type: type) type {
|
pub fn Table2ORM(comptime table_type: type) type {
|
||||||
|
const table_name = utils.getMemberDefaultValue(table_type, "name");
|
||||||
|
const struct_type = utils.getMemberDefaultValue(table_type, "layout");
|
||||||
|
|
||||||
const fields = std.meta.fields(table_type);
|
|
||||||
const field = fields[std.meta.fieldIndex(table_type, spacetime.MagicStruct).?];
|
|
||||||
const struct_type = @as(*const field.type, @alignCast(@ptrCast(field.default_value.?))).*;
|
|
||||||
const table_name: []const u8 = struct_type.name.?;
|
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
|
|
@ -282,7 +279,7 @@ pub fn Table2Struct(comptime table_type: type) type {
|
||||||
contents: []u8 = undefined,
|
contents: []u8 = undefined,
|
||||||
last_ret: i16 = spacetime.OK,
|
last_ret: i16 = spacetime.OK,
|
||||||
|
|
||||||
pub fn next(self: *@This()) !?*table_type {
|
pub fn next(self: *@This()) !?*struct_type {
|
||||||
var buffer_len: usize = undefined;
|
var buffer_len: usize = undefined;
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
|
|
@ -302,7 +299,7 @@ pub fn Table2Struct(comptime table_type: type) type {
|
||||||
|
|
||||||
switch(ret) {
|
switch(ret) {
|
||||||
spacetime.EXHAUSTED, spacetime.OK => {
|
spacetime.EXHAUSTED, spacetime.OK => {
|
||||||
return StructDeserializer(table_type)(self.allocator, &self.contents);
|
return StructDeserializer(struct_type)(self.allocator, &self.contents);
|
||||||
},
|
},
|
||||||
spacetime.BUFFER_TOO_SMALL => {
|
spacetime.BUFFER_TOO_SMALL => {
|
||||||
return error.BUFFER_TOO_SMALL;
|
return error.BUFFER_TOO_SMALL;
|
||||||
|
|
@ -321,10 +318,10 @@ pub fn Table2Struct(comptime table_type: type) type {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn insert(self: @This(), data: table_type) void {
|
pub fn insert(self: @This(), data: struct_type) void {
|
||||||
var id: TableId = undefined;
|
var id: TableId = undefined;
|
||||||
_ = spacetime.table_id_from_name(table_name.ptr, table_name.len, &id);
|
_ = spacetime.table_id_from_name(table_name.ptr, table_name.len, &id);
|
||||||
const raw_data = StructSerializer(table_type)(self.allocator, data) catch return;
|
const raw_data = StructSerializer(struct_type)(self.allocator, data) catch return;
|
||||||
defer self.allocator.free(raw_data);
|
defer self.allocator.free(raw_data);
|
||||||
var raw_data_len: usize = raw_data.len;
|
var raw_data_len: usize = raw_data.len;
|
||||||
_ = spacetime.datastore_insert_bsatn(id, raw_data.ptr, &raw_data_len);
|
_ = spacetime.datastore_insert_bsatn(id, raw_data.ptr, &raw_data_len);
|
||||||
|
|
@ -346,7 +343,7 @@ pub fn Table2Struct(comptime table_type: type) type {
|
||||||
pub const Local = struct {
|
pub const Local = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
pub fn get(self: @This(), table: anytype) Table2Struct(table) {
|
pub fn get(self: @This(), table: anytype) Table2ORM(table) {
|
||||||
return .{
|
return .{
|
||||||
.allocator = self.allocator,
|
.allocator = self.allocator,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
26
src/spacetime/utils.zig
Normal file
26
src/spacetime/utils.zig
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn getMemberDefaultType(t: type, comptime member: []const u8) type {
|
||||||
|
const field = std.meta.fields(t)[std.meta.fieldIndex(t, member).?];
|
||||||
|
return field.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getMemberDefaultValue(t: type, comptime member: []const u8) getMemberDefaultType(t, member) {
|
||||||
|
const field = std.meta.fields(t)[std.meta.fieldIndex(t, member).?];
|
||||||
|
const value = @as(*const field.type, @alignCast(@ptrCast(field.default_value))).*;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn itoa(comptime value: anytype) [:0]const u8 {
|
||||||
|
comptime var s: []const u8 = &[_]u8{};
|
||||||
|
comptime var n = value;
|
||||||
|
if (n == 0) {
|
||||||
|
s = s ++ .{'0'};
|
||||||
|
} else {
|
||||||
|
comptime while (n != 0) {
|
||||||
|
s = s ++ .{'0' + (n % 10)};
|
||||||
|
n = n / 10;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return @ptrCast(s ++ .{0});
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue