Add support for editing messages

This commit is contained in:
2025-08-15 01:38:54 -03:00
parent b9410bedd7
commit 12948dcc15
5 changed files with 320 additions and 130 deletions
+81 -34
View File
@@ -18,7 +18,7 @@ use twilight_model::{
user::User as TwilightUser,
};
use crate::{constants::DEFAULT_PREFIX, groups::calls::DisplayProfile, utils::get_random_u64};
use crate::{constants::DEFAULT_PREFIX, groups::calls::DisplayProfile, utils::{get_random_u64, i64_to_u64, u64_to_i64}};
#[derive(Debug, Error)]
pub enum DatabaseOrDiscordError {
@@ -44,34 +44,6 @@ pub enum DatabaseError {
DeserializationFailed,
}
/// Copies the bytes from [`i64`] to [`u64`].
///
/// WARNING: This does NOT keep the same "represented" value. This only keeps the bytes intact,
/// e.g. 0b0101 will still be 0b0101, but the value represented will change since the type changes.
///
/// Arguments:
/// * `i` - The [`i64`] to convert.
///
/// Returns:
/// [`u64`] - The resulting [`u64`].
fn i64_to_u64(i: i64) -> u64 {
u64::from_ne_bytes(i.to_ne_bytes())
}
/// Copies the bytes from [`u64`] to [`i64`].
///
/// WARNING: This does NOT keep the same "represented" value. This only keeps the bytes intact,
/// e.g. 0b0101 will still be 0b0101, but the value represented will change since the type changes.
///
/// Arguments:
/// * `u` - The [`u64`] to convert.
///
/// Returns:
/// [`i64`] - The resulting [`i64`].
fn u64_to_i64(u: u64) -> i64 {
i64::from_ne_bytes(u.to_ne_bytes())
}
trait Object<'a> {
type Row: DeserializeRow<'a, 'a>;
@@ -967,6 +939,11 @@ pub struct MessageBuilder {
message: Option<TwilightMessage>,
profile: Option<DisplayProfile>,
call_id: Option<u64>,
is_deleted: bool,
is_censored: bool,
propagation_message_id: Option<u64>,
propagation_channel_id: Option<u64>,
replying_to_id: Option<u64>,
}
impl MessageBuilder {
@@ -975,6 +952,11 @@ impl MessageBuilder {
message: None,
profile: None,
call_id: None,
is_deleted: false,
is_censored: false,
propagation_message_id: None,
propagation_channel_id: None,
replying_to_id: None,
}
}
@@ -993,6 +975,31 @@ impl MessageBuilder {
self
}
pub fn is_deleted(mut self, is_deleted: bool) -> Self {
self.is_deleted = is_deleted;
self
}
pub fn is_censored(mut self, is_censored: bool) -> Self {
self.is_censored = is_censored;
self
}
pub fn propagation_message_id(mut self, propagation_message_id: u64) -> Self {
self.propagation_message_id = Some(propagation_message_id);
self
}
pub fn propagation_channel_id(mut self, propagation_channel_id: u64) -> Self {
self.propagation_channel_id = Some(propagation_channel_id);
self
}
pub fn replying_to_id(mut self, replying_to_id: u64) -> Self {
self.replying_to_id = Some(replying_to_id);
self
}
pub fn build(self) -> Result<Message, MessageBuilderError> {
let message = self.message.ok_or(MessageBuilderError)?;
let profile = self.profile.ok_or(MessageBuilderError)?;
@@ -1011,12 +1018,12 @@ impl MessageBuilder {
.sticker_items
.first()
.map(|s| u64_to_i64(s.id.get())),
propagation_message_id: None,
propagation_channel_id: None,
replying_to_id: None,
is_deleted: false,
propagation_message_id: self.propagation_message_id.map(u64_to_i64),
propagation_channel_id: self.propagation_channel_id.map(u64_to_i64),
replying_to_id: self.replying_to_id.map(u64_to_i64),
is_deleted: self.is_deleted,
is_edited: message.edited_timestamp.is_some(),
is_censored: false,
is_censored: self.is_censored,
};
Ok(Message {
@@ -1063,6 +1070,46 @@ impl Message {
MessageBuilder::new()
}
pub async fn get_by_call_and_message_id(
call_id: u64,
message_id: u64,
session: &Session,
) -> Result<Option<Self>, DatabaseError> {
let call_id = u64_to_i64(call_id);
let message_id = u64_to_i64(message_id);
let result = session
.query_unpaged(
r#"
SELECT
call_id,
message_id,
author_id,
data
FROM
payphone.messages
WHERE
call_id = ? AND message_id = ?
LIMIT 1;
"#,
(call_id, message_id),
)
.await
.map_err(DatabaseError::QueryError)?
.into_rows_result()
.map_err(|_| DatabaseError::ResultNotRows)?;
match result.single_row::<<Message as Object>::Row>() {
Ok(row) => Ok(Some(Self::from_row(row))),
Err(error) => match error {
SingleRowError::DeserializationFailed(_) | SingleRowError::TypeCheckFailed(_) => {
Err(DatabaseError::DeserializationFailed)
}
SingleRowError::UnexpectedRowCount(_) => Ok(None),
},
}
}
pub async fn insert(&self, session: &Session) -> Result<(), DatabaseError> {
session
.query_unpaged(