using System.Net; using System.Text.Json; namespace DHT.Utils.Http; public static class JsonExtensions { public static bool HasKey(this JsonElement json, string key) { return json.TryGetProperty(key, out _); } public static JsonElement RequireObject(this JsonElement json, string key, string? path = null) { if (json.TryGetProperty(key, out var result)) { return result; } else { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + (path == null ? key : path + '.' + key) + "' to be an object."); } } public static JsonElement.ArrayEnumerator RequireArray(this JsonElement json, string key, string? path = null) { if (json.TryGetProperty(key, out var result) && result.ValueKind == JsonValueKind.Array) { return result.EnumerateArray(); } else { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + (path == null ? key : path + '.' + key) + "' to be an array."); } } public static string RequireString(this JsonElement json, string key, string path) { if (json.TryGetProperty(key, out var result) && result.ValueKind == JsonValueKind.String) { return result.ToString(); } else { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + path + '.' + key + "' to be a string."); } } public static bool RequireBool(this JsonElement json, string key, string path) { if (json.TryGetProperty(key, out var result) && result.ValueKind is JsonValueKind.True or JsonValueKind.False) { return result.GetBoolean(); } else { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + path + '.' + key + "' to be a boolean."); } } public static int RequireInt(this JsonElement json, string key, string path, int min = int.MinValue, int max = int.MaxValue) { if (json.TryGetProperty(key, out var result) && result.ValueKind == JsonValueKind.Number && result.TryGetInt32(out var i) && i >= min && i <= max) { return i; } else if (min == int.MinValue && max == int.MaxValue) { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + path + '.' + key + "' to be a 32-bit integer."); } else if (max == int.MaxValue) { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + path + '.' + key + "' to be a 32-bit integer (> " + min + ")."); } else if (min == int.MinValue) { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + path + '.' + key + "' to be a 32-bit integer (< " + max + ")."); } else { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + path + '.' + key + "' to be an integer (between " + min + " and " + max + ")."); } } public static long RequireLong(this JsonElement json, string key, string path, long min = long.MinValue, long max = long.MaxValue) { if (json.TryGetProperty(key, out var result) && result.ValueKind == JsonValueKind.Number && result.TryGetInt64(out var l) && l >= min && l <= max) { return l; } else if (min == long.MinValue && max == long.MaxValue) { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + path + '.' + key + "' to be a 64-bit integer."); } else if (max == long.MaxValue) { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + path + '.' + key + "' to be a 64-bit integer (> " + min + ")."); } else if (min == long.MinValue) { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + path + '.' + key + "' to be a 64-bit integer (< " + max + ")."); } else { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + path + '.' + key + "' to be an integer (between " + min + " and " + max + ")."); } } public static ulong RequireSnowflake(this JsonElement json, string key, string path) { if (ulong.TryParse(json.RequireString(key, path), out var snowflake)) { return snowflake; } else { throw new HttpException(HttpStatusCode.BadRequest, "Expected key '" + path + '.' + key + "' to be a Snowflake ID (64-bit unsigned integer in a string)."); } } }