From 82533d0c32a3e96b589173ad1a5ecffd48ecb1de Mon Sep 17 00:00:00 2001 From: Laci0503 Date: Sat, 20 Jul 2024 20:56:59 +0200 Subject: [PATCH] Rest API groundworks --- Discord.API/Rest/GetGatewayResponse.cs | 6 +++ Discord.API/Rest/RestClient.cs | 39 ++++++++++++++++++++ Discord.API/Rest/RestError.cs | 7 ++++ Discord.API/Rest/RestErrorResponse.cs | 12 ++++++ Discord.API/Rest/RestFailResponse.cs | 13 +++++++ Discord.API/Rest/RestResponse.cs | 12 ++++++ Discord.API/Rest/RestSuccessResponse.cs | 11 ++++++ Discord.API/SourceGenerationContext.cs | 8 +--- discord_api.sln | 8 ++-- model/{model.csproj => Discord.Model.csproj} | 0 10 files changed, 106 insertions(+), 10 deletions(-) create mode 100644 Discord.API/Rest/GetGatewayResponse.cs create mode 100644 Discord.API/Rest/RestClient.cs create mode 100644 Discord.API/Rest/RestError.cs create mode 100644 Discord.API/Rest/RestErrorResponse.cs create mode 100644 Discord.API/Rest/RestFailResponse.cs create mode 100644 Discord.API/Rest/RestResponse.cs create mode 100644 Discord.API/Rest/RestSuccessResponse.cs rename model/{model.csproj => Discord.Model.csproj} (100%) diff --git a/Discord.API/Rest/GetGatewayResponse.cs b/Discord.API/Rest/GetGatewayResponse.cs new file mode 100644 index 0000000..7098df4 --- /dev/null +++ b/Discord.API/Rest/GetGatewayResponse.cs @@ -0,0 +1,6 @@ +namespace Discord.API.Rest; + +public readonly struct GetGatewayResponse +{ + public required string Url {get; init;} +} diff --git a/Discord.API/Rest/RestClient.cs b/Discord.API/Rest/RestClient.cs new file mode 100644 index 0000000..f259f41 --- /dev/null +++ b/Discord.API/Rest/RestClient.cs @@ -0,0 +1,39 @@ +using System.Text.Json; + +namespace Discord.API.Rest; + +internal class RestClient{ + + private HttpClient httpClient; + + public RestClient(string base_url, string api_key){ + httpClient = new HttpClient(){ + BaseAddress=new Uri(base_url) + }; + httpClient.DefaultRequestHeaders.Add("Authorization", $"Bot {api_key}"); + httpClient.DefaultRequestHeaders.Add("User-Agent", $"DiscordBot ({Discord.API.StaticProperties.LibraryWebsite}, {Discord.API.StaticProperties.LibraryVersion})"); + } + + public async Task> GetGateway() => + await Get("gateway", s => JsonSerializer.Deserialize(s, SourceGenerationContext.Default.GetGatewayResponse)); + + private async Task> Get(string url, Func deserializer){ + try{ + HttpResponseMessage resp = await httpClient.GetAsync(url); + if(resp.IsSuccessStatusCode){ + return new RestSuccessResponse( + deserializer.Invoke(await resp.Content.ReadAsStringAsync()), + resp.StatusCode + ); + }else{ + return new RestErrorResponse( + JsonSerializer.Deserialize(await resp.Content.ReadAsStringAsync(), SourceGenerationContext.Default.RestError), + resp.StatusCode + ); + } + }catch (Exception ex){ + return new RestFailResponse(ex); + } + } + +} \ No newline at end of file diff --git a/Discord.API/Rest/RestError.cs b/Discord.API/Rest/RestError.cs new file mode 100644 index 0000000..383c956 --- /dev/null +++ b/Discord.API/Rest/RestError.cs @@ -0,0 +1,7 @@ +namespace Discord.API.Rest; + +public readonly struct RestError +{ + public required int Code {get; init;} + public required string Message {get; init;} +} diff --git a/Discord.API/Rest/RestErrorResponse.cs b/Discord.API/Rest/RestErrorResponse.cs new file mode 100644 index 0000000..aa1bcd6 --- /dev/null +++ b/Discord.API/Rest/RestErrorResponse.cs @@ -0,0 +1,12 @@ +using System.Net; +using Discord.API.Rest; + +namespace Discord.API; + +public class RestErrorResponse(RestError error, HttpStatusCode code) : RestResponse +{ + public override T Value => throw new InvalidOperationException(); + public override HttpStatusCode StatusCode => code; + public override bool Success => false; + public override RestError Error => error; +} diff --git a/Discord.API/Rest/RestFailResponse.cs b/Discord.API/Rest/RestFailResponse.cs new file mode 100644 index 0000000..f119294 --- /dev/null +++ b/Discord.API/Rest/RestFailResponse.cs @@ -0,0 +1,13 @@ +using System.Net; +using Discord.API.Rest; + +namespace Discord.API; + +public class RestFailResponse(Exception? ex) : RestResponse +{ + public override T Value => throw new InvalidOperationException(); + public override HttpStatusCode StatusCode => throw new InvalidOperationException(); + public override bool Success => false; + public override RestError Error => throw new InvalidOperationException(); + public Exception? Exception => ex; +} diff --git a/Discord.API/Rest/RestResponse.cs b/Discord.API/Rest/RestResponse.cs new file mode 100644 index 0000000..4f80e89 --- /dev/null +++ b/Discord.API/Rest/RestResponse.cs @@ -0,0 +1,12 @@ +using System.Net; +using Discord.API.Rest; + +namespace Discord.API; + +public abstract class RestResponse +{ + public abstract T Value {get;} + public abstract HttpStatusCode StatusCode {get;} + public abstract bool Success {get;} + public abstract RestError Error {get;} +} diff --git a/Discord.API/Rest/RestSuccessResponse.cs b/Discord.API/Rest/RestSuccessResponse.cs new file mode 100644 index 0000000..5d4e4a8 --- /dev/null +++ b/Discord.API/Rest/RestSuccessResponse.cs @@ -0,0 +1,11 @@ +using System.Net; + +namespace Discord.API.Rest; + +public class RestSuccessResponse(T response, HttpStatusCode code) : RestResponse +{ + public override T Value => response; + public override bool Success => true; + public override HttpStatusCode StatusCode => code; + public override RestError Error => throw new InvalidOperationException(); +} diff --git a/Discord.API/SourceGenerationContext.cs b/Discord.API/SourceGenerationContext.cs index 64a3b08..38ddc1a 100644 --- a/Discord.API/SourceGenerationContext.cs +++ b/Discord.API/SourceGenerationContext.cs @@ -14,12 +14,8 @@ namespace Discord.API; NumberHandling = JsonNumberHandling.AllowReadingFromString )] [JsonSerializable(typeof(GatewayPacket))] -[JsonSerializable(typeof(IdentifyPacket))] -[JsonSerializable(typeof(ChannelCreatePacket))] -[JsonSerializable(typeof(ChannelUpdatePacket))] -[JsonSerializable(typeof(ChannelDeletePacket))] -[JsonSerializable(typeof(DispatchPacket))] -[JsonSerializable(typeof(ReadyPacket))] +[JsonSerializable(typeof(Rest.GetGatewayResponse))] +[JsonSerializable(typeof(Rest.RestError))] internal partial class SourceGenerationContext : JsonSerializerContext { } \ No newline at end of file diff --git a/discord_api.sln b/discord_api.sln index c689fa3..6894c7c 100644 --- a/discord_api.sln +++ b/discord_api.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "model", "model\model.csproj", "{2FA8D012-CC43-4FBC-9520-CF627AB4BBEA}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.Model", "model\Discord.Model.csproj", "{2FA8D012-CC43-4FBC-9520-CF627AB4BBEA}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Discord.API", "Discord.API\Discord.API.csproj", "{5C77661B-670F-400B-AF77-E3EC062B673D}" EndProject @@ -16,9 +16,6 @@ Global Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {2FA8D012-CC43-4FBC-9520-CF627AB4BBEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2FA8D012-CC43-4FBC-9520-CF627AB4BBEA}.Debug|Any CPU.Build.0 = Debug|Any CPU @@ -37,4 +34,7 @@ Global {E89333A2-11C4-4CFF-9F45-32D951E871CA}.Release|Any CPU.ActiveCfg = Release|Any CPU {E89333A2-11C4-4CFF-9F45-32D951E871CA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal diff --git a/model/model.csproj b/model/Discord.Model.csproj similarity index 100% rename from model/model.csproj rename to model/Discord.Model.csproj