Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Value from Http #2806

Merged
merged 1 commit into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/builder/edit_role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ impl<'a> EditRole<'a> {
};

if let Some(position) = self.position {
http.edit_role_position(guild_id, role.id, position, self.audit_log_reason).await?;
guild_id
.edit_role_position_with_reason(http, role.id, position, self.audit_log_reason)
.await?;
Comment on lines -180 to +182
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This introduced a dependency on the model feature inside code that is normally just gated behind http plus builder. Is it possible to fix this?

Copy link
Member Author

@GnomedDev GnomedDev Mar 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to make a PR soon that moves builder inside of model and gets rid of the builder feature, since builder shouldn't be used without model anyway.

Copy link
Collaborator

@mkrasnitski mkrasnitski Mar 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate? I'm thinking of the builder-no-http usecase as a specific counter-example to that idea.

EDIT: It would be feasible to gate the execute methods behind model instead of just http, but the structs themselves I don't think should be gated behind model.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this to the lib-development chat as this is going quite off-topic for this PR.

}
Ok(role)
}
Expand Down
40 changes: 15 additions & 25 deletions src/http/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ impl Http {
pub async fn create_emoji(
&self,
guild_id: GuildId,
map: &Value,
map: &impl serde::Serialize,
audit_log_reason: Option<&str>,
) -> Result<Emoji> {
self.fire(Request {
Expand Down Expand Up @@ -580,7 +580,7 @@ impl Http {
/// over a [`Shard`], if at least one is running.
///
/// [`Shard`]: crate::gateway::Shard
pub async fn create_guild(&self, map: &Value) -> Result<PartialGuild> {
pub async fn create_guild(&self, map: &impl serde::Serialize) -> Result<PartialGuild> {
self.fire(Request {
body: Some(to_vec(map)?),
multipart: None,
Expand Down Expand Up @@ -619,7 +619,7 @@ impl Http {
&self,
guild_id: GuildId,
integration_id: IntegrationId,
map: &Value,
map: &impl serde::Serialize,
audit_log_reason: Option<&str>,
) -> Result<()> {
self.wind(204, Request {
Expand Down Expand Up @@ -716,7 +716,10 @@ impl Http {
}

/// Creates a private channel with a user.
pub async fn create_private_channel(&self, map: &Value) -> Result<PrivateChannel> {
pub async fn create_private_channel(
&self,
map: &impl serde::Serialize,
) -> Result<PrivateChannel> {
let body = to_vec(map)?;

self.fire(Request {
Expand Down Expand Up @@ -1386,7 +1389,7 @@ impl Http {
&self,
guild_id: GuildId,
emoji_id: EmojiId,
map: &Value,
map: &impl serde::Serialize,
audit_log_reason: Option<&str>,
) -> Result<Emoji> {
let body = to_vec(map)?;
Expand Down Expand Up @@ -1571,7 +1574,7 @@ impl Http {
pub async fn edit_guild_mfa_level(
&self,
guild_id: GuildId,
value: &Value,
value: &impl serde::Serialize,
audit_log_reason: Option<&str>,
) -> Result<MfaLevel> {
#[derive(Deserialize)]
Expand Down Expand Up @@ -1755,14 +1758,11 @@ impl Http {
pub async fn edit_nickname(
&self,
guild_id: GuildId,
new_nickname: Option<&str>,
map: &impl serde::Serialize,
audit_log_reason: Option<&str>,
) -> Result<()> {
let map = json!({ "nick": new_nickname });
let body = to_vec(&map)?;

self.wind(200, Request {
body: Some(body),
body: Some(to_vec(&map)?),
multipart: None,
headers: audit_log_reason.map(reason_into_header),
method: LightMethod::Patch,
Expand All @@ -1778,13 +1778,10 @@ impl Http {
pub async fn follow_news_channel(
&self,
news_channel_id: ChannelId,
target_channel_id: ChannelId,
map: &impl serde::Serialize,
) -> Result<FollowedChannel> {
let map = json!({ "webhook_channel_id": target_channel_id });
let body = to_vec(&map)?;

self.fire(Request {
body: Some(body),
body: Some(to_vec(&map)?),
multipart: None,
headers: None,
method: LightMethod::Post,
Expand Down Expand Up @@ -1895,19 +1892,12 @@ impl Http {
pub async fn edit_role_position(
&self,
guild_id: GuildId,
role_id: RoleId,
position: i16,
map: &impl serde::Serialize,
audit_log_reason: Option<&str>,
) -> Result<Vec<Role>> {
let map = json!([{
"id": role_id,
"position": position,
}]);
let body = to_vec(&map)?;

let mut value: Value = self
.fire(Request {
body: Some(body),
body: Some(to_vec(&map)?),
multipart: None,
headers: audit_log_reason.map(reason_into_header),
method: LightMethod::Patch,
Expand Down
11 changes: 10 additions & 1 deletion src/model/channel/channel_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,16 @@ impl ChannelId {
http: &Http,
target_channel_id: ChannelId,
) -> Result<FollowedChannel> {
http.follow_news_channel(self, target_channel_id).await
#[derive(serde::Serialize)]
struct FollowChannel {
webhook_channel_id: ChannelId,
}

let map = FollowChannel {
webhook_channel_id: target_channel_id,
};

http.follow_news_channel(self, &map).await
}

/// First attempts to retrieve the channel from the `temp_cache` if enabled, otherwise performs
Expand Down
98 changes: 78 additions & 20 deletions src/model/guild/guild_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use std::fmt;
#[cfg(feature = "model")]
use futures::stream::Stream;
use nonmax::{NonMaxU16, NonMaxU8};
use serde_json::json;

#[cfg(feature = "model")]
use crate::builder::{
Expand Down Expand Up @@ -331,12 +330,18 @@ impl GuildId {
/// [`EditProfile::avatar`]: crate::builder::EditProfile::avatar
/// [Create Guild Expressions]: Permissions::CREATE_GUILD_EXPRESSIONS
pub async fn create_emoji(self, http: &Http, name: &str, image: &str) -> Result<Emoji> {
let map = json!({
"name": name,
"image": image,
});
#[derive(serde::Serialize)]
struct CreateEmoji<'a> {
name: &'a str,
image: &'a str,
}

http.create_emoji(self, &map, None).await
let body = CreateEmoji {
name,
image,
};

http.create_emoji(self, &body, None).await
}

/// Creates an integration for the guild.
Expand All @@ -354,12 +359,19 @@ impl GuildId {
integration_id: IntegrationId,
kind: &str,
) -> Result<()> {
let map = json!({
"id": integration_id,
"type": kind,
});
#[derive(serde::Serialize)]
struct CreateIntegration<'a> {
id: IntegrationId,
#[serde(rename = "type")]
kind: &'a str,
}

let body = CreateIntegration {
id: integration_id,
kind,
};

http.create_guild_integration(self, integration_id, &map, None).await
http.create_guild_integration(self, integration_id, &body, None).await
}

/// Creates a new role in the guild with the data set, if any.
Expand Down Expand Up @@ -547,9 +559,14 @@ impl GuildId {
/// [Create Guild Expressions]: Permissions::CREATE_GUILD_EXPRESSIONS
/// [Manage Guild Expressions]: Permissions::MANAGE_GUILD_EXPRESSIONS
pub async fn edit_emoji(self, http: &Http, emoji_id: EmojiId, name: &str) -> Result<Emoji> {
let map = json!({
"name": name,
});
#[derive(serde::Serialize)]
struct EditEmoji<'a> {
name: &'a str,
}

let map = EditEmoji {
name,
};

http.edit_emoji(self, emoji_id, &map, None).await
}
Expand Down Expand Up @@ -604,10 +621,16 @@ impl GuildId {
mfa_level: MfaLevel,
audit_log_reason: Option<&str>,
) -> Result<MfaLevel> {
let value = json!({
"level": mfa_level,
});
http.edit_guild_mfa_level(self, &value, audit_log_reason).await
#[derive(serde::Serialize)]
struct EditMfaModel {
level: MfaLevel,
}

let map = EditMfaModel {
level: mfa_level,
};

http.edit_guild_mfa_level(self, &map, audit_log_reason).await
}

/// Edits the current user's nickname for the guild.
Expand All @@ -622,7 +645,16 @@ impl GuildId {
///
/// [Change Nickname]: Permissions::CHANGE_NICKNAME
pub async fn edit_nickname(self, http: &Http, new_nickname: Option<&str>) -> Result<()> {
http.edit_nickname(self, new_nickname, None).await
#[derive(serde::Serialize)]
struct EditNickname<'a> {
nick: Option<&'a str>,
}

let map = EditNickname {
nick: new_nickname,
};

http.edit_nickname(self, &map, None).await
}

/// Edits a [`Role`], optionally setting its new fields.
Expand Down Expand Up @@ -747,7 +779,33 @@ impl GuildId {
role_id: RoleId,
position: i16,
) -> Result<Vec<Role>> {
http.edit_role_position(self, role_id, position, None).await
self.edit_role_position_with_reason(http, role_id, position, None).await
}

/// Edit the position of a [`Role`] relative to all others in the [`Guild`].
///
/// # Errors
///
/// See [`GuildId::edit_role_position`] for more details.
pub async fn edit_role_position_with_reason(
self,
http: &Http,
role_id: RoleId,
position: i16,
reason: Option<&str>,
) -> Result<Vec<Role>> {
#[derive(serde::Serialize)]
struct EditRole {
id: RoleId,
position: i16,
}

let map = EditRole {
id: role_id,
position,
};

http.edit_role_position(self, &map, reason).await
}

/// Edits the guild's welcome screen.
Expand Down
16 changes: 11 additions & 5 deletions src/model/guild/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,12 +569,18 @@ impl Guild {
/// [`Shard`]: crate::gateway::Shard
/// [whitelist]: https://discord.com/developers/docs/resources/guild#create-guild
pub async fn create(http: &Http, name: &str, icon: Option<ImageHash>) -> Result<PartialGuild> {
let map = serde_json::json!({
"icon": icon,
"name": name,
});
#[derive(serde::Serialize)]
struct CreateGuild<'a> {
name: &'a str,
icon: Option<ImageHash>,
}

let body = CreateGuild {
name,
icon,
};

http.create_guild(&map).await
http.create_guild(&body).await
}

/// Creates a new [`Channel`] in the guild.
Expand Down
15 changes: 9 additions & 6 deletions src/model/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ use std::num::NonZeroU16;
use std::ops::{Deref, DerefMut};

use serde::{Deserialize, Serialize};
#[cfg(feature = "model")]
use serde_json::json;

use super::prelude::*;
#[cfg(feature = "model")]
Expand Down Expand Up @@ -636,11 +634,16 @@ impl UserId {
///
/// [current user]: CurrentUser
pub async fn create_dm_channel(self, cache_http: impl CacheHttp) -> Result<PrivateChannel> {
let map = json!({
"recipient_id": self,
});
#[derive(serde::Serialize)]
struct CreateDmChannel {
recipient_id: UserId,
}

let body = CreateDmChannel {
recipient_id: self,
};

cache_http.http().create_private_channel(&map).await
cache_http.http().create_private_channel(&body).await
}

/// First attempts to find a [`User`] by its Id in the cache, upon failure requests it via the
Expand Down
Loading