1use std::fmt::Display;
2use std::num::ParseIntError;
3use std::str::FromStr;
4
5pub use futures::future::BoxFuture;
6use serde::{de, Deserialize, Deserializer};
7
8pub mod client;
10pub mod events;
12pub mod http;
14pub mod player;
16pub mod search;
18pub mod track;
20
21#[derive(Clone, Default)]
22pub(crate) struct Secret(pub(crate) Box<str>);
23
24impl std::fmt::Debug for Secret {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 f.write_str("<hidden>")
27 }
28}
29
30#[derive(
31 Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Default, Serialize, Deserialize,
32)]
33#[cfg_attr(feature = "python", pyo3::pyclass)]
34pub struct UserId(pub u64);
36#[derive(
37 Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Default, Serialize, Deserialize,
38)]
39#[cfg_attr(feature = "python", pyo3::pyclass)]
40pub struct GuildId(pub u64);
42#[derive(
43 Hash, PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Default, Serialize, Deserialize,
44)]
45#[cfg_attr(feature = "python", pyo3::pyclass)]
46pub struct ChannelId(pub u64);
48
49impl FromStr for UserId {
50 type Err = ParseIntError;
51
52 fn from_str(s: &str) -> Result<Self, Self::Err> {
53 u64::from_str(s).map(Self)
54 }
55}
56
57impl FromStr for GuildId {
58 type Err = ParseIntError;
59
60 fn from_str(s: &str) -> Result<Self, Self::Err> {
61 u64::from_str(s).map(Self)
62 }
63}
64
65impl FromStr for ChannelId {
66 type Err = ParseIntError;
67
68 fn from_str(s: &str) -> Result<Self, Self::Err> {
69 u64::from_str(s).map(Self)
70 }
71}
72
73impl From<u64> for UserId {
74 fn from(i: u64) -> Self {
75 Self(i)
76 }
77}
78
79impl From<u64> for GuildId {
80 fn from(i: u64) -> Self {
81 Self(i)
82 }
83}
84
85impl From<u64> for ChannelId {
86 fn from(i: u64) -> Self {
87 Self(i)
88 }
89}
90
91pub(crate) fn deserialize_option_number<'de, D>(deserializer: D) -> Result<Option<u32>, D::Error>
92where
93 D: Deserializer<'de>,
94{
95 let n = i32::deserialize(deserializer)?;
96 Ok(match n.cmp(&-1) {
97 std::cmp::Ordering::Less => return Err(de::Error::custom("integer {n} is below -1")),
98 std::cmp::Ordering::Equal => None,
99 std::cmp::Ordering::Greater => Some(n.try_into().unwrap()),
100 })
101}
102
103pub(crate) fn deserialize_number_from_string<'de, T, D>(deserializer: D) -> Result<T, D::Error>
104where
105 D: serde::Deserializer<'de>,
106 T: FromStr + serde::Deserialize<'de>,
107 <T as FromStr>::Err: Display,
108{
109 #[derive(Deserialize)]
110 #[serde(untagged)]
111 enum StringOrInt<T> {
112 String(String),
113 Number(T),
114 }
115
116 match StringOrInt::<T>::deserialize(deserializer)? {
117 StringOrInt::String(s) => s.parse::<T>().map_err(serde::de::Error::custom),
118 StringOrInt::Number(i) => Ok(i),
119 }
120}
121
122#[cfg(feature = "serenity")]
123use serenity_dep::model::id::{
124 ChannelId as SerenityChannelId, GuildId as SerenityGuildId, UserId as SerenityUserId,
125};
126
127#[cfg(feature = "serenity")]
128impl From<SerenityUserId> for UserId {
129 fn from(id: SerenityUserId) -> UserId {
130 UserId(id.get().into())
131 }
132}
133
134#[cfg(feature = "serenity")]
135impl From<SerenityGuildId> for GuildId {
136 fn from(id: SerenityGuildId) -> GuildId {
137 GuildId(id.get().into())
138 }
139}
140
141#[cfg(feature = "serenity")]
142impl From<SerenityChannelId> for ChannelId {
143 fn from(id: SerenityChannelId) -> ChannelId {
144 ChannelId(id.get().into())
145 }
146}
147
148#[cfg(feature = "twilight")]
149use twilight_model::id::{
150 marker::{ChannelMarker, GuildMarker, UserMarker},
151 Id,
152};
153
154#[cfg(feature = "twilight")]
155impl From<Id<UserMarker>> for UserId {
156 fn from(id: Id<UserMarker>) -> UserId {
157 UserId(id.get())
158 }
159}
160
161#[cfg(feature = "twilight")]
162impl From<Id<GuildMarker>> for GuildId {
163 fn from(id: Id<GuildMarker>) -> GuildId {
164 GuildId(id.get())
165 }
166}
167
168#[cfg(feature = "twilight")]
169impl From<Id<ChannelMarker>> for ChannelId {
170 fn from(id: Id<ChannelMarker>) -> ChannelId {
171 ChannelId(id.get())
172 }
173}
174
175#[cfg(feature = "songbird")]
176use songbird_dep::id::{
177 ChannelId as SongbirdChannelId, GuildId as SongbirdGuildId, UserId as SongbirdUserId,
178};
179
180#[cfg(feature = "songbird")]
181impl From<SongbirdUserId> for UserId {
182 fn from(id: SongbirdUserId) -> UserId {
183 UserId(id.0.into())
184 }
185}
186
187#[cfg(feature = "songbird")]
188impl From<SongbirdGuildId> for GuildId {
189 fn from(id: SongbirdGuildId) -> GuildId {
190 GuildId(id.0.into())
191 }
192}
193
194#[cfg(feature = "songbird")]
195impl From<SongbirdChannelId> for ChannelId {
196 fn from(id: SongbirdChannelId) -> ChannelId {
197 ChannelId(id.0.into())
198 }
199}