add withdrawing from bank endpoints
This commit is contained in:
parent
0ffe638691
commit
166ff8e892
@ -22,9 +22,74 @@ token: ?[]u8 = null,
|
||||
|
||||
item_codes: std.ArrayList([]u8),
|
||||
|
||||
pub const APIErrors = error {
|
||||
pub const APIError = error {
|
||||
RequestFailed,
|
||||
ParseFailed
|
||||
ParseFailed,
|
||||
OutOfMemory
|
||||
};
|
||||
|
||||
pub const MoveError = APIError || error {
|
||||
MapNotFound,
|
||||
CharacterIsBusy,
|
||||
CharacterAtDestination,
|
||||
CharacterNotFound,
|
||||
CharacterInCooldown
|
||||
};
|
||||
|
||||
pub const FightError = APIError || error {
|
||||
CharacterIsBusy,
|
||||
CharacterIsFull,
|
||||
CharacterNotFound,
|
||||
CharacterInCooldown,
|
||||
MonsterNotFound,
|
||||
};
|
||||
|
||||
pub const GatheringError = APIError || error {
|
||||
CharacterIsBusy,
|
||||
CharacterMissingSkill,
|
||||
CharacterIsFull,
|
||||
CharacterNotFound,
|
||||
CharacterInCooldown,
|
||||
ResourceNotFound
|
||||
};
|
||||
|
||||
pub const BankDepositItemError = APIError || error {
|
||||
ItemNotFound,
|
||||
BankIsBusy,
|
||||
NotEnoughItems,
|
||||
CharacterIsBusy,
|
||||
CharacterNotFound,
|
||||
CharacterInCooldown,
|
||||
BankNotFound
|
||||
};
|
||||
|
||||
pub const BankDepositGoldError = APIError || error {
|
||||
BankIsBusy,
|
||||
NotEnoughGold,
|
||||
CharacterIsBusy,
|
||||
CharacterNotFound,
|
||||
CharacterInCooldown,
|
||||
BankNotFound
|
||||
};
|
||||
|
||||
pub const BankWithdrawGoldError = APIError || error {
|
||||
BankIsBusy,
|
||||
NotEnoughGold,
|
||||
CharacterIsBusy,
|
||||
CharacterNotFound,
|
||||
CharacterInCooldown,
|
||||
BankNotFound
|
||||
};
|
||||
|
||||
pub const BankWithdrawItemError = APIError || error {
|
||||
ItemNotFound,
|
||||
BankIsBusy,
|
||||
NotEnoughItems,
|
||||
CharacterIsBusy,
|
||||
CharacterIsFull,
|
||||
CharacterNotFound,
|
||||
CharacterInCooldown,
|
||||
BankNotFound
|
||||
};
|
||||
|
||||
const ServerStatus = struct {
|
||||
@ -33,7 +98,7 @@ const ServerStatus = struct {
|
||||
version: []const u8,
|
||||
characters_online: i64,
|
||||
|
||||
fn parse(api: *ArtifactsAPI, object: json.ObjectMap, allocator: Allocator) !ServerStatus {
|
||||
pub fn parse(api: *ArtifactsAPI, object: json.ObjectMap, allocator: Allocator) !ServerStatus {
|
||||
_ = api;
|
||||
|
||||
return ServerStatus{
|
||||
@ -152,7 +217,7 @@ pub const Cooldown = struct {
|
||||
expiration: f64,
|
||||
reason: Reason,
|
||||
|
||||
fn parse(obj: json.ObjectMap) !Cooldown {
|
||||
pub fn parse(obj: json.ObjectMap) !Cooldown {
|
||||
const reason = try json_utils.getStringRequired(obj, "reason");
|
||||
const expiration = try json_utils.getStringRequired(obj, "expiration");
|
||||
|
||||
@ -210,7 +275,7 @@ pub const FightResult = struct {
|
||||
cooldown: Cooldown,
|
||||
fight: Details,
|
||||
|
||||
fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !FightResult {
|
||||
pub fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !FightResult {
|
||||
const cooldown = json_utils.getObject(obj, "cooldown") orelse return error.MissingProperty;
|
||||
const fight = json_utils.getObject(obj, "fight") orelse return error.MissingProperty;
|
||||
|
||||
@ -219,6 +284,17 @@ pub const FightResult = struct {
|
||||
.fight = try Details.parse(api, fight)
|
||||
};
|
||||
}
|
||||
|
||||
pub fn parseError(status: std.http.Status) ?FightError {
|
||||
return switch (@intFromEnum(status)) {
|
||||
486 => return FightError.CharacterIsBusy,
|
||||
497 => return FightError.CharacterIsFull,
|
||||
498 => return FightError.CharacterNotFound,
|
||||
499 => return FightError.CharacterInCooldown,
|
||||
598 => return FightError.MonsterNotFound,
|
||||
else => return null
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const GatheringResult = struct {
|
||||
@ -254,7 +330,7 @@ pub const GatheringResult = struct {
|
||||
cooldown: Cooldown,
|
||||
details: Details,
|
||||
|
||||
fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !GatheringResult {
|
||||
pub fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !GatheringResult {
|
||||
const cooldown = json_utils.getObject(obj, "cooldown") orelse return error.MissingProperty;
|
||||
const details = json_utils.getObject(obj, "details") orelse return error.MissingProperty;
|
||||
|
||||
@ -263,12 +339,24 @@ pub const GatheringResult = struct {
|
||||
.details = try Details.parse(api, details)
|
||||
};
|
||||
}
|
||||
|
||||
pub fn parseError(status: std.http.Status) ?GatheringError {
|
||||
return switch (@intFromEnum(status)) {
|
||||
486 => return GatheringError.CharacterIsBusy,
|
||||
493 => return GatheringError.CharacterMissingSkill,
|
||||
497 => return GatheringError.CharacterIsFull,
|
||||
498 => return GatheringError.CharacterNotFound,
|
||||
499 => return GatheringError.CharacterInCooldown,
|
||||
598 => return GatheringError.ResourceNotFound,
|
||||
else => null
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const MoveResult = struct {
|
||||
cooldown: Cooldown,
|
||||
|
||||
fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !MoveResult {
|
||||
pub fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !MoveResult {
|
||||
_ = api;
|
||||
|
||||
const cooldown = json_utils.getObject(obj, "cooldown") orelse return error.MissingProperty;
|
||||
@ -278,6 +366,17 @@ pub const MoveResult = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn parseError(status: std.http.Status) ?MoveError {
|
||||
return switch (@intFromEnum(status)) {
|
||||
404 => return MoveError.MapNotFound,
|
||||
486 => return MoveError.CharacterIsBusy,
|
||||
490 => return MoveError.CharacterAtDestination,
|
||||
498 => return MoveError.CharacterNotFound,
|
||||
499 => return MoveError.CharacterInCooldown,
|
||||
else => null
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: MoveResult) void {
|
||||
_ = self;
|
||||
}
|
||||
@ -286,7 +385,7 @@ pub const MoveResult = struct {
|
||||
pub const GoldTransactionResult = struct {
|
||||
cooldown: Cooldown,
|
||||
|
||||
fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !GoldTransactionResult {
|
||||
pub fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !GoldTransactionResult {
|
||||
_ = api;
|
||||
const cooldown = json_utils.getObject(obj, "cooldown") orelse return error.MissingProperty;
|
||||
|
||||
@ -295,6 +394,31 @@ pub const GoldTransactionResult = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn parseDepositError(status: std.http.Status) ?BankDepositGoldError {
|
||||
return switch (@intFromEnum(status)) {
|
||||
461 => return BankDepositGoldError.BankIsBusy,
|
||||
478 => return BankDepositGoldError.NotEnoughGold, // TODO: This should maybe be removed
|
||||
486 => return BankDepositGoldError.CharacterIsBusy,
|
||||
492 => return BankDepositGoldError.NotEnoughGold,
|
||||
498 => return BankDepositGoldError.CharacterNotFound,
|
||||
499 => return BankDepositGoldError.CharacterInCooldown,
|
||||
598 => return BankDepositGoldError.BankNotFound,
|
||||
else => return null
|
||||
};
|
||||
}
|
||||
|
||||
pub fn parseWithdrawError(status: std.http.Status) ?BankWithdrawGoldError {
|
||||
return switch (@intFromEnum(status)) {
|
||||
460 => return BankWithdrawGoldError.NotEnoughGold,
|
||||
461 => return BankWithdrawGoldError.BankIsBusy,
|
||||
486 => return BankWithdrawGoldError.CharacterIsBusy,
|
||||
498 => return BankWithdrawGoldError.CharacterNotFound,
|
||||
499 => return BankWithdrawGoldError.CharacterInCooldown,
|
||||
598 => return BankWithdrawGoldError.BankNotFound,
|
||||
else => return null
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: GoldTransactionResult) void {
|
||||
_ = self;
|
||||
}
|
||||
@ -303,7 +427,7 @@ pub const GoldTransactionResult = struct {
|
||||
pub const ItemTransactionResult = struct {
|
||||
cooldown: Cooldown,
|
||||
|
||||
fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !ItemTransactionResult {
|
||||
pub fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !ItemTransactionResult {
|
||||
_ = api;
|
||||
const cooldown = json_utils.getObject(obj, "cooldown") orelse return error.MissingProperty;
|
||||
|
||||
@ -312,6 +436,33 @@ pub const ItemTransactionResult = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn parseDepositError(status: std.http.Status) ?BankDepositItemError {
|
||||
return switch (@intFromEnum(status)) {
|
||||
404 => return BankDepositItemError.ItemNotFound,
|
||||
461 => return BankDepositItemError.BankIsBusy,
|
||||
478 => return BankDepositItemError.NotEnoughItems,
|
||||
486 => return BankDepositItemError.CharacterIsBusy,
|
||||
498 => return BankDepositItemError.CharacterNotFound,
|
||||
499 => return BankDepositItemError.CharacterInCooldown,
|
||||
598 => return BankDepositItemError.BankNotFound,
|
||||
else => return null
|
||||
};
|
||||
}
|
||||
|
||||
pub fn parseWithdrawError(status: std.http.Status) ?BankWithdrawItemError {
|
||||
return switch (@intFromEnum(status)) {
|
||||
404 => return BankWithdrawItemError.ItemNotFound,
|
||||
461 => return BankWithdrawItemError.BankIsBusy,
|
||||
478 => return BankWithdrawItemError.NotEnoughItems,
|
||||
486 => return BankWithdrawItemError.CharacterIsBusy,
|
||||
497 => return BankWithdrawItemError.CharacterIsFull,
|
||||
498 => return BankWithdrawItemError.CharacterNotFound,
|
||||
499 => return BankWithdrawItemError.CharacterInCooldown,
|
||||
598 => return BankWithdrawItemError.BankNotFound,
|
||||
else => return null
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: ItemTransactionResult) void {
|
||||
_ = self;
|
||||
}
|
||||
@ -351,7 +502,17 @@ pub fn deinit(self: *ArtifactsAPI) void {
|
||||
self.item_codes.deinit();
|
||||
}
|
||||
|
||||
fn fetch(self: *ArtifactsAPI, method: std.http.Method, path: []const u8, payload: ?[]const u8) !ArtifactsFetchResult {
|
||||
const FetchOptions = struct {
|
||||
method: std.http.Method,
|
||||
path: []const u8,
|
||||
payload: ?[]const u8 = null
|
||||
};
|
||||
|
||||
fn fetch(self: *ArtifactsAPI, options: FetchOptions) !ArtifactsFetchResult {
|
||||
const method = options.method;
|
||||
const path = options.path;
|
||||
const payload = options.payload;
|
||||
|
||||
std.log.debug("fetch {} {s}", .{method, path});
|
||||
var uri = self.server_uri;
|
||||
uri.path = .{ .raw = path };
|
||||
@ -390,7 +551,7 @@ fn fetch(self: *ArtifactsAPI, method: std.http.Method, path: []const u8, payload
|
||||
|
||||
const parsed = try json.parseFromSliceLeaky(json.Value, arena.allocator(), response_body, .{ .allocate = .alloc_if_needed });
|
||||
if (parsed != json.Value.object) {
|
||||
return APIErrors.ParseFailed;
|
||||
return APIError.ParseFailed;
|
||||
}
|
||||
|
||||
return ArtifactsFetchResult{
|
||||
@ -400,20 +561,63 @@ fn fetch(self: *ArtifactsAPI, method: std.http.Method, path: []const u8, payload
|
||||
};
|
||||
}
|
||||
|
||||
fn fetchAndParseObject(self: *ArtifactsAPI, Result: type, method: std.http.Method, path: []const u8, payload: ?[]const u8, args: anytype) !Result {
|
||||
const result = try self.fetch(method, path, payload);
|
||||
fn fetchOptionalObject(
|
||||
self: *ArtifactsAPI,
|
||||
Error: type,
|
||||
parseError: ?fn (status: std.http.Status) ?Error,
|
||||
Object: type,
|
||||
parseObject: anytype,
|
||||
parseObjectArgs: anytype,
|
||||
fetchOptions: FetchOptions,
|
||||
) Error!?Object {
|
||||
if (@typeInfo(@TypeOf(parseObject)) != .Fn) {
|
||||
@compileError("`parseObject` must be a function");
|
||||
}
|
||||
|
||||
const result = self.fetch(fetchOptions) catch return APIError.RequestFailed;
|
||||
defer result.deinit();
|
||||
|
||||
if (result.status != .ok) {
|
||||
return APIErrors.RequestFailed;
|
||||
}
|
||||
if (result.body == null) {
|
||||
return APIErrors.ParseFailed;
|
||||
if (Error != APIError) {
|
||||
if (parseError == null) {
|
||||
@compileError("`parseError` must be defined, if `Error` is not `APIError`");
|
||||
}
|
||||
|
||||
if (parseError.?(result.status)) |error_value| {
|
||||
return error_value;
|
||||
}
|
||||
} else {
|
||||
if (parseError != null) {
|
||||
@compileError("`parseError` must be null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const body = json_utils.asObject(result.body.?) orelse return APIErrors.ParseFailed;
|
||||
return @call(.auto, Result.parse, .{ self, body } ++ args) catch return APIErrors.ParseFailed;
|
||||
// return Result.parse(self.allocator, body) catch return APIErrors.ParseFailed;
|
||||
if (result.status == .not_found) {
|
||||
return null;
|
||||
}
|
||||
if (result.status != .ok) {
|
||||
return APIError.RequestFailed;
|
||||
}
|
||||
if (result.body == null) {
|
||||
return APIError.ParseFailed;
|
||||
}
|
||||
|
||||
const body = json_utils.asObject(result.body.?) orelse return APIError.ParseFailed;
|
||||
return @call(.auto, parseObject, .{ self, body } ++ parseObjectArgs) catch return APIError.ParseFailed;
|
||||
}
|
||||
|
||||
fn fetchObject(
|
||||
self: *ArtifactsAPI,
|
||||
Error: type,
|
||||
parseError: ?fn (status: std.http.Status) ?Error,
|
||||
Object: type,
|
||||
parseObject: anytype,
|
||||
parseObjectArgs: anytype,
|
||||
fetchOptions: FetchOptions
|
||||
) Error!Object {
|
||||
const result = try self.fetchOptionalObject(Error, parseError, Object, parseObject, parseObjectArgs, fetchOptions);
|
||||
return result orelse return APIError.RequestFailed;
|
||||
}
|
||||
|
||||
pub fn setServer(self: *ArtifactsAPI, url: []const u8) !void {
|
||||
@ -465,31 +669,43 @@ pub fn getItemCode(self: *const ArtifactsAPI, id: ItemId) ?[]const u8 {
|
||||
// ------------------------- Endpoints ------------------------
|
||||
|
||||
pub fn getServerStatus(self: *ArtifactsAPI) !ServerStatus {
|
||||
return try self.fetchAndParseObject(ServerStatus, .GET, "/", null, .{ self.allocator });
|
||||
return try self.fetchObject(
|
||||
APIError,
|
||||
null,
|
||||
ServerStatus,
|
||||
ServerStatus.parse, .{ self.allocator },
|
||||
.{ .method = .GET, .path = "/" }
|
||||
);
|
||||
}
|
||||
|
||||
pub fn getCharacter(self: *ArtifactsAPI, name: []const u8) !Character {
|
||||
pub fn getCharacter(self: *ArtifactsAPI, name: []const u8) !?Character {
|
||||
const path = try std.fmt.allocPrint(self.allocator, "/characters/{s}", .{name});
|
||||
defer self.allocator.free(path);
|
||||
|
||||
return try self.fetchAndParseObject(Character, .GET, path, null, .{ self.allocator });
|
||||
return try self.fetchOptionalObject(
|
||||
APIError,
|
||||
null,
|
||||
Character,
|
||||
Character.parse, .{ self.allocator },
|
||||
.{ .method = .GET, .path = path }
|
||||
);
|
||||
}
|
||||
|
||||
pub fn listMyCharacters(self: *ArtifactsAPI) !CharacterList {
|
||||
const path = try std.fmt.allocPrint(self.allocator, "/my/characters", .{});
|
||||
defer self.allocator.free(path);
|
||||
|
||||
const result = try self.fetch(.GET, path, null);
|
||||
const result = try self.fetch(.{ .method = .GET, .path = path });
|
||||
defer result.deinit();
|
||||
|
||||
if (result.status != .ok) {
|
||||
return APIErrors.RequestFailed;
|
||||
return APIError.RequestFailed;
|
||||
}
|
||||
if (result.body == null) {
|
||||
return APIErrors.ParseFailed;
|
||||
return APIError.ParseFailed;
|
||||
}
|
||||
|
||||
const body = json_utils.asArray(result.body.?) orelse return APIErrors.ParseFailed;
|
||||
const body = json_utils.asArray(result.body.?) orelse return APIError.ParseFailed;
|
||||
|
||||
var characters = try std.ArrayList(Character).initCapacity(self.allocator, body.items.len);
|
||||
errdefer {
|
||||
@ -500,8 +716,8 @@ pub fn listMyCharacters(self: *ArtifactsAPI) !CharacterList {
|
||||
}
|
||||
|
||||
for (body.items) |character_json| {
|
||||
const character_obj = json_utils.asObject(character_json) orelse return APIErrors.ParseFailed;
|
||||
const char = Character.parse(character_obj, self.allocator, self) catch return APIErrors.ParseFailed;
|
||||
const character_obj = json_utils.asObject(character_json) orelse return APIError.ParseFailed;
|
||||
const char = Character.parse(character_obj, self.allocator, self) catch return APIError.ParseFailed;
|
||||
|
||||
characters.appendAssumeCapacity(char);
|
||||
}
|
||||
@ -512,48 +728,128 @@ pub fn listMyCharacters(self: *ArtifactsAPI) !CharacterList {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn actionFight(self: *ArtifactsAPI, name: []const u8) !FightResult {
|
||||
pub fn actionFight(self: *ArtifactsAPI, name: []const u8) FightError!FightResult {
|
||||
const path = try std.fmt.allocPrint(self.allocator, "/my/{s}/action/fight", .{name});
|
||||
defer self.allocator.free(path);
|
||||
|
||||
return try self.fetchAndParseObject(FightResult, .POST, path, null, .{ });
|
||||
return try self.fetchObject(
|
||||
FightError,
|
||||
FightResult.parseError,
|
||||
FightResult,
|
||||
FightResult.parse, .{ },
|
||||
.{ .method = .POST, .path = path }
|
||||
);
|
||||
}
|
||||
|
||||
pub fn actionGathering(self: *ArtifactsAPI, name: []const u8) !GatheringResult {
|
||||
pub fn actionGathering(self: *ArtifactsAPI, name: []const u8) GatheringError!GatheringResult {
|
||||
const path = try std.fmt.allocPrint(self.allocator, "/my/{s}/action/gathering", .{name});
|
||||
defer self.allocator.free(path);
|
||||
|
||||
return try self.fetchAndParseObject(GatheringResult, .POST, path, null, .{ });
|
||||
return try self.fetchObject(
|
||||
GatheringError,
|
||||
GatheringResult.parseError,
|
||||
GatheringResult,
|
||||
GatheringResult.parse, .{ },
|
||||
.{ .method = .POST, .path = path }
|
||||
);
|
||||
}
|
||||
|
||||
pub fn actionMove(self: *ArtifactsAPI, name: []const u8, x: i64, y: i64) !MoveResult {
|
||||
pub fn actionMove(self: *ArtifactsAPI, name: []const u8, x: i64, y: i64) MoveError!MoveResult {
|
||||
const path = try std.fmt.allocPrint(self.allocator, "/my/{s}/action/move", .{name});
|
||||
defer self.allocator.free(path);
|
||||
|
||||
const payload = try std.fmt.allocPrint(self.allocator, "{{ \"x\":{},\"y\":{} }}", .{x, y});
|
||||
defer self.allocator.free(payload);
|
||||
|
||||
return try self.fetchAndParseObject(MoveResult, .POST, path, payload, .{});
|
||||
return try self.fetchObject(
|
||||
MoveError,
|
||||
MoveResult.parseError,
|
||||
MoveResult,
|
||||
MoveResult.parse, .{ },
|
||||
.{ .method = .POST, .path = path, .payload = payload }
|
||||
);
|
||||
}
|
||||
|
||||
pub fn actionBankDepositGold(self: *ArtifactsAPI, name: []const u8, quantity: u64) !GoldTransactionResult {
|
||||
pub fn actionBankDepositGold(
|
||||
self: *ArtifactsAPI,
|
||||
name: []const u8,
|
||||
quantity: u64
|
||||
) BankDepositGoldError!GoldTransactionResult {
|
||||
const path = try std.fmt.allocPrint(self.allocator, "/my/{s}/action/bank/deposit/gold", .{name});
|
||||
defer self.allocator.free(path);
|
||||
|
||||
const payload = try std.fmt.allocPrint(self.allocator, "{{ \"quantity\":{} }}", .{quantity});
|
||||
defer self.allocator.free(payload);
|
||||
|
||||
return try self.fetchAndParseObject(GoldTransactionResult, .POST, path, payload, .{});
|
||||
return try self.fetchObject(
|
||||
BankDepositGoldError,
|
||||
GoldTransactionResult.parseDepositError,
|
||||
GoldTransactionResult,
|
||||
GoldTransactionResult.parse, .{ },
|
||||
.{ .method = .POST, .path = path, .payload = payload }
|
||||
);
|
||||
}
|
||||
|
||||
pub fn actionBankDepositItem(self: *ArtifactsAPI, name: []const u8, code: []const u8, quantity: u64) !ItemTransactionResult {
|
||||
pub fn actionBankDepositItem(
|
||||
self: *ArtifactsAPI,
|
||||
name: []const u8,
|
||||
code: []const u8,
|
||||
quantity: u64
|
||||
) BankDepositItemError!ItemTransactionResult {
|
||||
const path = try std.fmt.allocPrint(self.allocator, "/my/{s}/action/bank/deposit", .{name});
|
||||
defer self.allocator.free(path);
|
||||
|
||||
const payload = try std.fmt.allocPrint(self.allocator, "{{ \"code\":\"{s}\",\"quantity\":{} }}", .{code, quantity});
|
||||
defer self.allocator.free(payload);
|
||||
|
||||
return try self.fetchAndParseObject(ItemTransactionResult, .POST, path, payload, .{});
|
||||
return try self.fetchObject(
|
||||
BankDepositItemError,
|
||||
ItemTransactionResult.parseDepositError,
|
||||
ItemTransactionResult,
|
||||
ItemTransactionResult.parse, .{ },
|
||||
.{ .method = .POST, .path = path, .payload = payload }
|
||||
);
|
||||
}
|
||||
|
||||
pub fn actionBankWithdrawGold(
|
||||
self: *ArtifactsAPI,
|
||||
name: []const u8,
|
||||
quantity: u64
|
||||
) BankDepositGoldError!GoldTransactionResult {
|
||||
const path = try std.fmt.allocPrint(self.allocator, "/my/{s}/action/bank/withdraw/gold", .{name});
|
||||
defer self.allocator.free(path);
|
||||
|
||||
const payload = try std.fmt.allocPrint(self.allocator, "{{ \"quantity\":{} }}", .{quantity});
|
||||
defer self.allocator.free(payload);
|
||||
|
||||
return try self.fetchObject(
|
||||
BankWithdrawGoldError,
|
||||
GoldTransactionResult.parseWithdrawError,
|
||||
GoldTransactionResult,
|
||||
GoldTransactionResult.parse, .{ },
|
||||
.{ .method = .POST, .path = path, .payload = payload }
|
||||
);
|
||||
}
|
||||
|
||||
pub fn actionBankWithdrawItem(
|
||||
self: *ArtifactsAPI,
|
||||
name: []const u8,
|
||||
code: []const u8,
|
||||
quantity: u64
|
||||
) BankWithdrawItemError!ItemTransactionResult {
|
||||
const path = try std.fmt.allocPrint(self.allocator, "/my/{s}/action/bank/withdraw", .{name});
|
||||
defer self.allocator.free(path);
|
||||
|
||||
const payload = try std.fmt.allocPrint(self.allocator, "{{ \"code\":\"{s}\",\"quantity\":{} }}", .{code, quantity});
|
||||
defer self.allocator.free(payload);
|
||||
|
||||
return try self.fetchObject(
|
||||
BankWithdrawItemError,
|
||||
ItemTransactionResult.parseWithdrawError,
|
||||
ItemTransactionResult,
|
||||
ItemTransactionResult.parse, .{ },
|
||||
.{ .method = .POST, .path = path, .payload = payload }
|
||||
);
|
||||
}
|
||||
|
||||
test "parse date time" {
|
||||
|
Loading…
Reference in New Issue
Block a user