diff --git a/src/grom/user/current_user.gleam b/src/grom/user/current_user.gleam index ab973df..a462daa 100644 --- a/src/grom/user/current_user.gleam +++ b/src/grom/user/current_user.gleam @@ -1,4 +1,5 @@ import gleam/bool +import gleam/dynamic/decode import gleam/http import gleam/http/request import gleam/int @@ -8,9 +9,11 @@ import gleam/option.{type Option, None, Some} import gleam/result import gleam/string import grom +import grom/guild import grom/guild_member.{type GuildMember} import grom/image import grom/internal/rest +import grom/permission.{type Permission} import grom/user.{type User} // TYPES ---------------------------------------------------------------------- @@ -24,16 +27,67 @@ pub type Modify { } pub type GetGuildsQuery { - BeforeId(String) - AfterId(String) - Limit(Int) - WithCounts(Bool) + GetGuildsBeforeId(String) + GetGuildsAfterId(String) + GetGuildsLimit(Int) + /// Refers to the approximate_member and approximate_presence counts + GetGuildsWithCounts(Bool) +} + +pub type PartialGuild { + PartialGuild( + id: String, + name: String, + icon_hash: Option(String), + banner_hash: Option(String), + is_current_user_owner: Bool, + current_user_permissions: List(Permission), + features: List(guild.Feature), + approximate_member_count: Option(Int), + approximate_presence_count: Option(Int), + ) +} + +// DECODERS ------------------------------------------------------------------- + +fn partial_guild_decoder() -> decode.Decoder(PartialGuild) { + use id <- decode.field("id", decode.string) + use name <- decode.field("name", decode.string) + use icon_hash <- decode.field("icon", decode.optional(decode.string)) + use banner_hash <- decode.field("banner", decode.optional(decode.string)) + use is_current_user_owner <- decode.field("owner", decode.bool) + use current_user_permissions <- decode.field( + "permissions", + permission.decoder(), + ) + use features <- decode.field("features", decode.list(guild.feature_decoder())) + use approximate_member_count <- decode.optional_field( + "approximate_member_count", + None, + decode.optional(decode.int), + ) + use approximate_presence_count <- decode.optional_field( + "approximate_presence_count", + None, + decode.optional(decode.int), + ) + decode.success(PartialGuild( + id:, + name:, + icon_hash:, + banner_hash:, + is_current_user_owner:, + current_user_permissions:, + features:, + approximate_member_count:, + approximate_presence_count:, + )) } // ENCODERS -------------------------------------------------------------------- @internal -pub fn modify_encode(modify: Modify) -> Json { +pub fn modify_to_json(modify: Modify) -> Json { let Modify(username:, avatar:, banner:) = modify let username = case username { Some(name) -> [#("username", json.string(name))] @@ -73,7 +127,7 @@ pub fn modify( client: grom.Client, with data: Modify, ) -> Result(User, grom.Error) { - let json = data |> modify_encode + let json = data |> modify_to_json use response <- result.try( client |> rest.new_request(http.Patch, "/users/@me") @@ -93,14 +147,14 @@ pub fn new_modify() -> Modify { pub fn get_guilds( client: grom.Client, with query: List(GetGuildsQuery), -) -> Result(User, grom.Error) { +) -> Result(List(PartialGuild), grom.Error) { let query = list.map(query, fn(parameter) { case parameter { - BeforeId(id) -> #("before", id) - AfterId(id) -> #("after", id) - Limit(limit) -> #("limit", limit |> int.to_string) - WithCounts(with_counts) -> #( + GetGuildsBeforeId(id) -> #("before", id) + GetGuildsAfterId(id) -> #("after", id) + GetGuildsLimit(limit) -> #("limit", limit |> int.to_string) + GetGuildsWithCounts(with_counts) -> #( "with_counts", with_counts |> bool.to_string @@ -117,7 +171,7 @@ pub fn get_guilds( ) response.body - |> json.parse(using: user.decoder()) + |> json.parse(using: decode.list(of: partial_guild_decoder())) |> result.map_error(grom.CouldNotDecode) } diff --git a/test/grom_test.gleam b/test/grom_test.gleam index bbc976f..3aaced5 100644 --- a/test/grom_test.gleam +++ b/test/grom_test.gleam @@ -17,7 +17,7 @@ pub fn main() { pub fn encode_modify_current_test() { current_user.Modify(..current_user.new_modify(), username: Some("fo1o")) - |> current_user.modify_encode + |> current_user.modify_to_json |> json.to_string |> should.equal("{\"username\":\"fo1o\"}") }