#
I've just one-shotted an iterator with a lifetime in #rust. Is this what it feels like when the language finally clicks?
Personal Blog about anything - mostly programming, cooking and random thoughts
I've just one-shotted an iterator with a lifetime in #rust. Is this what it feels like when the language finally clicks?
#gamedev progress:
I've started working on a minimal TOML parser in #zig for my game. This is already enough to parse a file into a map of structs. I'm really impressed by the comptime type info.
const std = @import("std");
const ParserError = error{
MissingEqual,
MissingBraket,
MissingQuote,
UnsupportedType,
};
pub fn parse_file(
comptime T: type,
allocator: std.mem.Allocator,
file_name: []const u8,
) !std.StringHashMap(T) {
var map = std.StringHashMap(T).init(allocator);
var file = try std.fs.cwd().openFile(file_name, .{});
defer file.close();
var buf_reader = std.io.bufferedReader(file.reader());
var in_stream = buf_reader.reader();
var buf: [1024]u8 = undefined;
var name: ?[]const u8 = null;
var cur_item: T = undefined;
while (try in_stream.readUntilDelimiterOrEof(&buf, '\n')) |line| {
const clean = std.mem.trim(u8, line, &std.ascii.whitespace);
// skip empty
if (clean.len == 0) {
continue;
}
if (clean[0] == '[') {
if (name != null) {
try map.put(name.?, cur_item);
}
const name_split_idx = std.mem.indexOf(u8, clean, "]") orelse return ParserError.MissingBraket;
name = try allocator.dupe(u8, clean[1..name_split_idx]);
continue;
}
const split_idx = try (std.mem.indexOf(u8, clean, "=") orelse ParserError.MissingEqual);
const field_name = std.mem.trim(u8, clean[0..split_idx], &std.ascii.whitespace);
const value = std.mem.trim(u8, clean[split_idx + 1 ..], &std.ascii.whitespace);
const type_info = comptime @typeInfo(T);
const fields = comptime type_info.@"struct".fields;
inline for (fields) |field| {
if (std.mem.eql(u8, field_name, field.name)) {
switch (field.type) {
f32, f64 => |Float| {
@field(cur_item, field.name) = try std.fmt.parseFloat(Float, value);
},
u8, u32, u64, i8, i32, i64 => |Int| {
@field(cur_item, field.name) = try std.fmt.parseInt(Int, value, 10);
},
[]u8 => {
if (value[0] != '"' or value[value.len - 1] != '"') {
return ParserError.MissingQuote;
}
@field(cur_item, field.name) = try allocator.dupe(u8, value[1 .. value.len - 1]);
},
else => {
return ParserError.UnsupportedType;
},
}
break;
}
}
}
if (name != null) {
try map.put(name.?, cur_item);
}
return map;
}
https://techhub.social/@ajfriesen/115226740616849332
Maybe you should use owl-blogs ;)
Your blog is missing the webfinger. This is used my most fediverse services to check if an account exists and to get all needed infos. Maybe this helps to debug this.
https://ajfriesen.com/.well-known/webfinger/?resource=acct:blog@ajfriesen.com
https://blog.libove.org/.well-known/webfinger?resource=acct:h4kor@blog.libove.org
https://techhub.social/@ajfriesen/115226277282594821
Ping
https://mastodon.social/users/theludovyc/statuses/115221493624209415
Not everything has to be OOP. This would add an new indirection and spread the logic.
https://mastodon.social/users/alefunguju/statuses/115221726510108005
I always list these asserts at the top of functions to make clear what the function is expecting. It's not necessary but makes it very clear where the function can be used.
refactored hero logic into state pattern. So much better!
https://mastodon.social/users/theludovyc/statuses/115206856592029811
At the moment it is just called "Tavern Game" :D. The idea is to run a tavern in a fantasy world. Adventurers come to you before their quests for equipment.
#gamedev progress:
enum
to distinguish between different items. This would become infeasible once I start adding more items. Rework to have a generic item struct.