Skip to main content

neptunium_http/endpoints/channel/
update_channel_settings.rs

1use std::collections::HashMap;
2
3use bon::Builder;
4use neptunium_model::{
5    channel::{Channel, ChannelType, PermissionOverwrite, VoiceRegion},
6    id::{
7        Id,
8        marker::{ChannelMarker, UserMarker},
9    },
10    time::duration::{Duration, representation::Seconds},
11};
12use reqwest::Method;
13use serde::Serialize;
14use serde_json::{Number, Value};
15
16use crate::{endpoints::Endpoint, request::Request};
17
18/*
19 * TODO: So, might just want to have a single struct instead of all this enum stuff, even though it
20 * makes the code "less correct". Might have to choose DX over correctness, idk...
21 * -> Maybe have this be as correct as possible but the neptunium crate implements nice abstractions
22 * for DX or something
23 */
24
25#[derive(Serialize, Builder, Clone, Debug)]
26pub struct GuildTextChannelSettingsUpdates {
27    /// 1-1024 characters.
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub topic: Option<String>,
30    /// The parent category.
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub parent_id: Option<Id<ChannelMarker>>,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub permission_overwrites: Option<Vec<PermissionOverwrite>>,
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub nsfw: Option<bool>,
37    /// Slowmode delay. Must be `0 <= delay <= 21600` (21600 seconds = 6 hours).
38    #[serde(
39        skip_serializing_if = "Option::is_none",
40        rename = "rate_limit_per_user"
41    )]
42    pub slowmode: Option<Duration<Seconds>>,
43    /// The channel name.
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub name: Option<String>,
46}
47
48#[derive(Serialize, Builder, Clone, Debug)]
49pub struct GuildVoiceChannelSettingsUpdates {
50    /// 1-1024 characters.
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub topic: Option<String>,
53    /// The parent category.
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub parent_id: Option<Id<ChannelMarker>>,
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub permission_overwrites: Option<Vec<PermissionOverwrite>>,
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub nsfw: Option<bool>,
60    /// Slowmode delay. Must be `0 <= delay <= 21600` (21600 seconds = 6 hours).
61    #[serde(
62        skip_serializing_if = "Option::is_none",
63        rename = "rate_limit_per_user"
64    )]
65    pub slowmode: Option<Duration<Seconds>>,
66    /// The channel name.
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub name: Option<String>,
69    /// The voice channel bitrate in bits per second (8000-320000).
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub bitrate: Option<u32>,
72    /// Maximum users allowed in the voice channel. 0-99, where 0 means unlimited.
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub user_limit: Option<u8>,
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub rtc_region: Option<VoiceRegion>,
77}
78
79#[derive(Serialize, Builder, Clone, Debug)]
80pub struct GroupDmChannelSettingsUpdates {
81    /// 1-1024 characters.
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub topic: Option<String>,
84    /// The parent category.
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub parent_id: Option<Id<ChannelMarker>>,
87    #[serde(skip_serializing_if = "Option::is_none")]
88    pub permission_overwrites: Option<Vec<PermissionOverwrite>>,
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub nsfw: Option<bool>,
91    /// Slowmode delay. Must be `0 <= delay <= 21600` (21600 seconds = 6 hours).
92    #[serde(
93        skip_serializing_if = "Option::is_none",
94        rename = "rate_limit_per_user"
95    )]
96    pub slowmode: Option<Duration<Seconds>>,
97    /// The channel name.
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub name: Option<String>,
100    /// Base64 encoded icon image.
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub icon: Option<String>,
103    /// The new owner.
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub owner_id: Option<Id<UserMarker>>,
106    /// Custom nicknames for users in this group DM. Set a value in the `HashMap` to `None` to clear the custom name.
107    #[serde(skip_serializing_if = "Option::is_none")]
108    pub nicks: Option<HashMap<Id<UserMarker>, Option<String>>>,
109}
110
111#[derive(Serialize, Builder, Clone, Debug)]
112pub struct GuildCategoryChannelSettingsUpdates {
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub permission_overwrites: Option<Vec<PermissionOverwrite>>,
115    /// The channel name.
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub name: Option<String>,
118}
119
120#[derive(Serialize, Builder, Clone, Debug)]
121pub struct GuildLinkChannelSettingsUpdates {
122    /// The parent category.
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub parent_id: Option<Id<ChannelMarker>>,
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub permission_overwrites: Option<Vec<PermissionOverwrite>>,
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub name: Option<String>,
129    #[serde(skip_serializing_if = "Option::is_none")]
130    pub url: Option<String>,
131}
132
133#[derive(Clone, Debug)]
134pub enum ChannelSettingsUpdates {
135    GuildText(GuildTextChannelSettingsUpdates),
136    GuildVoice(GuildVoiceChannelSettingsUpdates),
137    GroupDm(GroupDmChannelSettingsUpdates),
138    GuildCategory(GuildCategoryChannelSettingsUpdates),
139    GuildLink(GuildLinkChannelSettingsUpdates),
140}
141
142impl Serialize for ChannelSettingsUpdates {
143    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
144    where
145        S: serde::Serializer,
146    {
147        let mut body = match &self {
148            Self::GuildText(data) => serde_json::to_value(data).unwrap(),
149            Self::GuildVoice(data) => serde_json::to_value(data).unwrap(),
150            Self::GroupDm(data) => serde_json::to_value(data).unwrap(),
151            Self::GuildCategory(data) => serde_json::to_value(data).unwrap(),
152            Self::GuildLink(data) => serde_json::to_value(data).unwrap(),
153        };
154        let channel_type = match self {
155            Self::GuildText(_) => ChannelType::GuildText,
156            Self::GuildVoice(_) => ChannelType::GuildVoice,
157            Self::GroupDm(_) => ChannelType::GroupDm,
158            Self::GuildCategory(_) => ChannelType::GuildCategory,
159            Self::GuildLink(_) => ChannelType::GuildLink,
160        } as u16;
161
162        body["type"] = Value::Number(Number::from_u128(u128::from(channel_type)).unwrap());
163
164        body.serialize(serializer)
165    }
166}
167
168#[derive(Builder, Clone, Debug)]
169pub struct UpdateChannelSettings {
170    pub channel_id: Id<ChannelMarker>,
171    pub updates: ChannelSettingsUpdates,
172}
173
174impl Endpoint for UpdateChannelSettings {
175    type Response = Channel;
176
177    fn into_request(self) -> crate::request::Request {
178        let req = Request::builder()
179            .path(format!("/channels/{}", self.channel_id))
180            .method(Method::PATCH);
181        req.body(serde_json::to_string(&self.updates).unwrap())
182            .build()
183    }
184}