const std = @import("std"); const ErrorDefinition = struct { name: [:0]const u8, code: ?u10, fn init(name: [:0]const u8, code: ?u10) ErrorDefinition { return ErrorDefinition{ .name = name, .code = code }; } }; fn ErrorDefinitionList(errors: []const ErrorDefinition) type { var errorNames: [errors.len]std.builtin.Type.Error = undefined; for (0.., errors) |i, def| { errorNames[i] = .{ .name = def.name }; } const error_set = @Type(.{ .ErrorSet = &errorNames }); return struct { const ErrorSet = error_set; fn parse(status: std.http.Status) ?ErrorSet { inline for (errors) |err| { if (err.code == @intFromEnum(status)) { return @field(ErrorSet, err.name); } } return null; } }; } const ServerUnavailable = ErrorDefinition.init("ServerUnavailable", 503); const RequestFailed = ErrorDefinition.init("RequestFailed", null); const ParseFailed = ErrorDefinition.init("ParseFailed", null); const OutOfMemory = ErrorDefinition.init("OutOfMemory", null); const MapNotFound = ErrorDefinition.init("MapNotFound", 404); const ItemNotFound = ErrorDefinition.init("ItemNotFound", 404); const RecipeNotFound = ErrorDefinition.init("RecipeNotFound", 404); const BankIsBusy = ErrorDefinition.init("BankIsBusy", 461); const NotEnoughItems = ErrorDefinition.init("NotEnoughItems", 478); const SlotIsFull = ErrorDefinition.init("SlotIsFull", 485); const CharacterIsBusy = ErrorDefinition.init("CharacterIsBusy", 486); const AlreadyHasTask = ErrorDefinition.init("AlreadyHasTask", 486); const CharacterAtDestination = ErrorDefinition.init("CharacterAtDestination", 490); const SlotIsEmpty = ErrorDefinition.init("SlotIsEmpty", 491); const NotEnoughGold = ErrorDefinition.init("NotEnoughGold", 492); const NotEnoughSkill = ErrorDefinition.init("NotEnoughSkill", 493); const CharacterIsFull = ErrorDefinition.init("CharacterIsFull", 497); const CharacterNotFound = ErrorDefinition.init("CharacterNotFound", 498); const CharacterInCooldown = ErrorDefinition.init("CharacterInCooldown", 499); const BankNotFound = ErrorDefinition.init("BankNotFound", 598); const MonsterNotFound = ErrorDefinition.init("MonsterNotFound", 598); const ResourceNotFound = ErrorDefinition.init("ResourceNotFound", 598); const WorkshopNotFound = ErrorDefinition.init("WorkshopNotFound", 598); const TaskMasterNotFound = ErrorDefinition.init("TaskMasterNotFound", 598); pub const FetchError = ErrorDefinitionList(&[_]ErrorDefinition{ ServerUnavailable, RequestFailed, ParseFailed, OutOfMemory, }).ErrorSet; const MoveErrorDef = ErrorDefinitionList(&[_]ErrorDefinition{ MapNotFound, CharacterIsBusy, CharacterAtDestination, CharacterNotFound, CharacterInCooldown }); pub const MoveError = FetchError || MoveErrorDef.ErrorSet; pub const parseMoveError = MoveErrorDef.parse; const FightErrorDef = ErrorDefinitionList(&[_]ErrorDefinition{ CharacterIsBusy, CharacterIsFull, CharacterNotFound, CharacterInCooldown, MonsterNotFound, }); pub const FightError = FetchError || FightErrorDef.ErrorSet; pub const parseFightError = FightErrorDef.parse; const GatherErrorDef = ErrorDefinitionList(&[_]ErrorDefinition{ CharacterIsBusy, NotEnoughSkill, CharacterIsFull, CharacterNotFound, CharacterInCooldown, ResourceNotFound }); pub const GatherError = FetchError || GatherErrorDef.ErrorSet; pub const parseGatherError = GatherErrorDef.parse; const BankDepositItemErrorDef = ErrorDefinitionList(&[_]ErrorDefinition{ ItemNotFound, BankIsBusy, NotEnoughItems, CharacterIsBusy, CharacterNotFound, CharacterInCooldown, BankNotFound }); pub const BankDepositItemError = FetchError || BankDepositItemErrorDef.ErrorSet; pub const parseBankDepositItemError = BankDepositItemErrorDef.parse; const BankDepositGoldErrorDef = ErrorDefinitionList(&[_]ErrorDefinition{ BankIsBusy, NotEnoughGold, CharacterIsBusy, CharacterNotFound, CharacterInCooldown, BankNotFound }); pub const BankDepositGoldError = FetchError || BankDepositGoldErrorDef.ErrorSet; pub const parseBankDepositGoldError = BankDepositGoldErrorDef.parse; const BankWithdrawGoldErrorDef = ErrorDefinitionList(&[_]ErrorDefinition{ BankIsBusy, NotEnoughGold, CharacterIsBusy, CharacterNotFound, CharacterInCooldown, BankNotFound }); pub const BankWithdrawGoldError = FetchError || BankWithdrawGoldErrorDef.ErrorSet; pub const parseBankWithdrawGoldError = BankWithdrawGoldErrorDef.parse; const BankWithdrawItemErrorDef = ErrorDefinitionList(&[_]ErrorDefinition{ ItemNotFound, BankIsBusy, NotEnoughItems, CharacterIsBusy, CharacterIsFull, CharacterNotFound, CharacterInCooldown, BankNotFound }); pub const BankWithdrawItemError = FetchError || BankWithdrawItemErrorDef.ErrorSet; pub const parseBankWithdrawItemError = BankWithdrawItemErrorDef.parse; const CraftErrorDef = ErrorDefinitionList(&[_]ErrorDefinition{ RecipeNotFound, NotEnoughItems, CharacterIsBusy, NotEnoughSkill, CharacterIsFull, CharacterNotFound, CharacterInCooldown, WorkshopNotFound }); pub const CraftError = FetchError || CraftErrorDef.ErrorSet; pub const parseCraftError = CraftErrorDef.parse; const UnequipErrorDef = ErrorDefinitionList(&[_]ErrorDefinition{ ItemNotFound, // TODO: Can this really occur? maybe a bug in docs CharacterIsBusy, SlotIsEmpty, CharacterIsFull, CharacterNotFound, CharacterInCooldown, }); pub const UnequipError = FetchError || UnequipErrorDef.ErrorSet; pub const parseUnequipError = UnequipErrorDef.parse; const EquipErrorDef = ErrorDefinitionList(&[_]ErrorDefinition{ ItemNotFound, SlotIsFull, CharacterIsBusy, NotEnoughSkill, CharacterNotFound, CharacterInCooldown, }); pub const EquipError = FetchError || EquipErrorDef.ErrorSet; pub const parseEquipError = EquipErrorDef.parse; const TaskAcceptErrorDef = ErrorDefinitionList(&[_]ErrorDefinition{ CharacterIsBusy, AlreadyHasTask, CharacterNotFound, CharacterInCooldown, TaskMasterNotFound }); pub const TaskAcceptError = FetchError || TaskAcceptErrorDef.ErrorSet; pub const parseTaskAcceptError = TaskAcceptErrorDef.parse;