const c = @import("c.zig").c; const std = @import("std"); const debug = @import("std").debug; pub fn expectEvent(parser: *c.yaml_parser_t, expectedType: c.yaml_event_type_t) !void { var event: c.yaml_event_t = undefined; if (c.yaml_parser_parse(parser, &event) != 1) return error.YAMLParserError; defer c.yaml_event_delete(&event); if (event.type != expectedType) { debug.print("unexpected event: {}\n", .{event.type}); return error.InvalidConfiguration; } } pub fn parseStringEvent(event: *c.yaml_event_t, allocator: std.mem.Allocator) ![]const u8 { if (event.type != c.YAML_SCALAR_EVENT) return error.InvalidType; const data = event.data.scalar; const value: []const u8 = data.value[0..data.length]; return try allocator.dupe(u8, value); } pub fn parseString(parser: *c.yaml_parser_t, allocator: std.mem.Allocator) ![]const u8 { var event: c.yaml_event_t = undefined; if (c.yaml_parser_parse(parser, &event) != 1) return error.YAMLParserError; defer c.yaml_event_delete(&event); return parseStringEvent(&event, allocator); } pub fn parseInt(parser: *c.yaml_parser_t, comptime T: type) !T { var event: c.yaml_event_t = undefined; if (c.yaml_parser_parse(parser, &event) != 1) return error.YAMLParserError; defer c.yaml_event_delete(&event); if (event.type != c.YAML_SCALAR_EVENT) return error.InvalidType; const data = event.data.scalar; const value: []const u8 = data.value[0..data.length]; return try std.fmt.parseInt(T, value, 10); } pub fn parseEnum(parser: *c.yaml_parser_t, comptime T: type) !T { var event: c.yaml_event_t = undefined; if (c.yaml_parser_parse(parser, &event) != 1) return error.YAMLParserError; defer c.yaml_event_delete(&event); if (event.type != c.YAML_SCALAR_EVENT) return error.InvalidType; const data = event.data.scalar; const value: []const u8 = data.value[0..data.length]; inline for (@typeInfo(T).@"enum".fields) |field| { if (std.mem.eql(u8, value, field.name)) return @field(T, field.name); } return error.InvalidValue; } pub fn parseUnion(parser: *c.yaml_parser_t, comptime T: type, allocator: std.mem.Allocator) !T { _ = parser; _ = allocator; // sorry, i lost this code in a git accident and have since moved on 🤡 unreachable; } pub fn parseBool(parser: *c.yaml_parser_t) !bool { var event: c.yaml_event_t = undefined; if (c.yaml_parser_parse(parser, &event) != 1) return error.YAMLParserError; defer c.yaml_event_delete(&event); if (event.type != c.YAML_SCALAR_EVENT) return error.InvalidType; const data = event.data.scalar; const value: []const u8 = data.value[0..data.length]; if (data.style != c.YAML_PLAIN_SCALAR_STYLE) return false; return std.mem.eql(u8, value, "true") or std.mem.eql(u8, value, "1"); } pub fn skipAny(parser: *c.yaml_parser_t) !void { var event: c.yaml_event_t = undefined; var depth: u32 = 0; while (true) { if (c.yaml_parser_parse(parser, &event) != 1) return error.YAMLParserError; defer c.yaml_event_delete(&event); switch (event.type) { c.YAML_SCALAR_EVENT => { if (depth == 0) break; }, c.YAML_SEQUENCE_START_EVENT, c.YAML_MAPPING_START_EVENT, => depth += 1, c.YAML_SEQUENCE_END_EVENT, c.YAML_MAPPING_END_EVENT, => { depth -= 1; if (depth == 0) break; }, else => { debug.print("unexpected event: {}\n", .{event.type}); return error.InvalidConfiguration; }, } } }