chore: switch to method chaining over macro

This commit is contained in:
Zomatree
2025-08-12 03:12:27 +01:00
parent 789dedd9f1
commit 1a60aecdb3
7 changed files with 112 additions and 119 deletions

View File

@@ -14,7 +14,6 @@ use futures::{
FutureExt, SinkExt, StreamExt, TryStreamExt, FutureExt, SinkExt, StreamExt, TryStreamExt,
}; };
use redis_kiss::{PayloadType, REDIS_PAYLOAD_TYPE, REDIS_URI}; use redis_kiss::{PayloadType, REDIS_PAYLOAD_TYPE, REDIS_URI};
use revolt_config::report_internal_error;
use revolt_database::{ use revolt_database::{
events::{client::EventV1, server::ClientMessage}, events::{client::EventV1, server::ClientMessage},
iso8601_timestamp::Timestamp, iso8601_timestamp::Timestamp,
@@ -27,7 +26,7 @@ use async_std::{
sync::{Mutex, RwLock}, sync::{Mutex, RwLock},
task::spawn, task::spawn,
}; };
use revolt_result::create_error; use revolt_result::{create_error, ToRevoltError};
use sentry::Level; use sentry::Level;
use crate::config::{ProtocolConfiguration, WebsocketHandshakeCallback}; use crate::config::{ProtocolConfiguration, WebsocketHandshakeCallback};
@@ -110,21 +109,21 @@ pub async fn client(db: &'static Database, stream: TcpStream, addr: SocketAddr)
let user_id = state.cache.user_id.clone(); let user_id = state.cache.user_id.clone();
// Notify socket we have authenticated. // Notify socket we have authenticated.
if report_internal_error!(write.send(config.encode(&EventV1::Authenticated)).await).is_err() { if write.send(config.encode(&EventV1::Authenticated)).await.to_internal_error().is_err() {
return; return;
} }
// Download required data to local cache and send Ready payload. // Download required data to local cache and send Ready payload.
let ready_payload = match report_internal_error!( let ready_payload = match state
state
.generate_ready_payload(db, config.get_ready_payload_fields()) .generate_ready_payload(db, config.get_ready_payload_fields())
.await .await
) { .to_internal_error()
{
Ok(ready_payload) => ready_payload, Ok(ready_payload) => ready_payload,
Err(_) => return, Err(_) => return,
}; };
if report_internal_error!(write.send(config.encode(&ready_payload)).await).is_err() { if write.send(config.encode(&ready_payload)).await.to_internal_error().is_err() {
return; return;
} }
@@ -219,14 +218,15 @@ async fn listener(
write: &Mutex<WsWriter>, write: &Mutex<WsWriter>,
) { ) {
let redis_config = RedisConfig::from_url(&REDIS_URI).unwrap(); let redis_config = RedisConfig::from_url(&REDIS_URI).unwrap();
let subscriber = match report_internal_error!( let subscriber = match fred::types::Builder::from_config(redis_config)
fred::types::Builder::from_config(redis_config).build_subscriber_client() .build_subscriber_client()
) { .to_internal_error()
{
Ok(subscriber) => subscriber, Ok(subscriber) => subscriber,
Err(_) => return, Err(_) => return,
}; };
if report_internal_error!(subscriber.init().await).is_err() { if subscriber.init().await.to_internal_error().is_err() {
return; return;
} }
@@ -249,13 +249,13 @@ async fn listener(
// Check for state changes for subscriptions. // Check for state changes for subscriptions.
match state.apply_state().await { match state.apply_state().await {
SubscriptionStateChange::Reset => { SubscriptionStateChange::Reset => {
if report_internal_error!(subscriber.unsubscribe_all().await).is_err() { if subscriber.unsubscribe_all().await.to_internal_error().is_err() {
break 'out; break 'out;
} }
let subscribed = state.subscribed.read().await; let subscribed = state.subscribed.read().await;
for id in subscribed.iter() { for id in subscribed.iter() {
if report_internal_error!(subscriber.subscribe(id).await).is_err() { if subscriber.subscribe(id).await.to_internal_error().is_err() {
break 'out; break 'out;
} }
} }
@@ -268,7 +268,7 @@ async fn listener(
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
info!("{addr:?} unsubscribing from {id}"); info!("{addr:?} unsubscribing from {id}");
if report_internal_error!(subscriber.unsubscribe(id).await).is_err() { if subscriber.unsubscribe(id).await.to_internal_error().is_err() {
break 'out; break 'out;
} }
} }
@@ -277,7 +277,7 @@ async fn listener(
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
info!("{addr:?} subscribing to {id}"); info!("{addr:?} subscribing to {id}");
if report_internal_error!(subscriber.subscribe(id).await).is_err() { if subscriber.subscribe(id).await.to_internal_error().is_err() {
break 'out; break 'out;
} }
} }
@@ -302,7 +302,7 @@ async fn listener(
_ = t2 => {}, _ = t2 => {},
message = t1 => { message = t1 => {
// Handle incoming events. // Handle incoming events.
let message = match report_internal_error!(message) { let message = match message.to_internal_error() {
Ok(message) => message, Ok(message) => message,
Err(_) => break 'out Err(_) => break 'out
}; };
@@ -311,15 +311,15 @@ async fn listener(
PayloadType::Json => message PayloadType::Json => message
.value .value
.as_str() .as_str()
.and_then(|s| report_internal_error!(serde_json::from_str::<EventV1>(s.as_ref())).ok()), .and_then(|s| serde_json::from_str::<EventV1>(s.as_ref()).to_internal_error().ok()),
PayloadType::Msgpack => message PayloadType::Msgpack => message
.value .value
.as_bytes() .as_bytes()
.and_then(|b| report_internal_error!(rmp_serde::from_slice::<EventV1>(b)).ok()), .and_then(|b| rmp_serde::from_slice::<EventV1>(b).to_internal_error().ok()),
PayloadType::Bincode => message PayloadType::Bincode => message
.value .value
.as_bytes() .as_bytes()
.and_then(|b| report_internal_error!(bincode::deserialize::<EventV1>(b)).ok()), .and_then(|b| bincode::deserialize::<EventV1>(b).to_internal_error().ok()),
}; };
let Some(mut event) = event else { let Some(mut event) = event else {
@@ -379,7 +379,7 @@ async fn listener(
} }
} }
report_internal_error!(subscriber.quit().await).ok(); subscriber.quit().await.to_internal_error().ok();
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]

View File

@@ -1,7 +1,7 @@
use bson::to_document; use bson::to_document;
use bson::Document; use bson::Document;
use revolt_config::report_internal_error;
use revolt_result::Result; use revolt_result::Result;
use revolt_result::ToRevoltError;
use crate::File; use crate::File;
use crate::FileUsedFor; use crate::FileUsedFor;
@@ -106,7 +106,7 @@ impl AbstractAttachments for MongoDb {
}, },
doc! { doc! {
"$set": { "$set": {
"used_for": report_internal_error!(to_document(&used_for))?, "used_for": to_document(&used_for).to_internal_error()?,
"uploader_id": uploader_id "uploader_id": uploader_id
} }
}, },

View File

@@ -55,13 +55,12 @@ pub async fn fetch_from_s3(bucket_id: &str, path: &str, nonce: &str) -> Result<V
// Send a request for the file // Send a request for the file
let mut obj = let mut obj =
report_internal_error!(client.get_object().bucket(bucket_id).key(path).send().await)?; client.get_object().bucket(bucket_id).key(path).send().await.to_internal_error()?;
// Read the file from remote // Read the file from remote
let mut buf = vec![]; let mut buf = vec![];
while let Some(bytes) = obj.body.next().await { while let Some(bytes) = obj.body.next().await {
let data = report_internal_error!(bytes)?; buf.write_all(&bytes.to_internal_error()?).to_internal_error()?;
report_internal_error!(buf.write_all(&data))?;
// is there a more efficient way to do this? // is there a more efficient way to do this?
// we just want the Vec<u8> // we just want the Vec<u8>
} }
@@ -100,15 +99,14 @@ pub async fn upload_to_s3(bucket_id: &str, path: &str, buf: &[u8]) -> Result<Str
.to_internal_error()?; .to_internal_error()?;
// Upload the file to remote // Upload the file to remote
report_internal_error!( client
client .put_object()
.put_object() .bucket(bucket_id)
.bucket(bucket_id) .key(path)
.key(path) .body(buf.into())
.body(buf.into()) .send()
.send() .await
.await .to_internal_error()?;
)?;
Ok(BASE64_STANDARD.encode(nonce)) Ok(BASE64_STANDARD.encode(nonce))
} }
@@ -118,14 +116,13 @@ pub async fn delete_from_s3(bucket_id: &str, path: &str) -> Result<()> {
let config = config().await; let config = config().await;
let client = create_client(config.files.s3); let client = create_client(config.files.s3);
report_internal_error!( client
client .delete_object()
.delete_object() .bucket(bucket_id)
.bucket(bucket_id) .key(path)
.key(path) .send()
.send() .await
.await .to_internal_error()?;
)?;
Ok(()) Ok(())
} }
@@ -145,8 +142,7 @@ pub fn image_size(f: &NamedTempFile) -> Option<(usize, usize)> {
pub fn image_size_vec(v: &[u8], mime: &str) -> Option<(usize, usize)> { pub fn image_size_vec(v: &[u8], mime: &str) -> Option<(usize, usize)> {
match mime { match mime {
"image/svg+xml" => { "image/svg+xml" => {
let tree = let tree = usvg::Tree::from_data(v, &Default::default()).to_internal_error().ok()?;
report_internal_error!(usvg::Tree::from_data(v, &Default::default())).ok()?;
let size = tree.size(); let size = tree.size();
Some((size.width() as usize, size.height() as usize)) Some((size.width() as usize, size.height() as usize))
@@ -221,9 +217,9 @@ pub fn decode_image<R: Read + BufRead + Seek>(reader: &mut R, mime: &str) -> Res
"image/svg+xml" => { "image/svg+xml" => {
// usvg doesn't support Read trait so copy to buffer // usvg doesn't support Read trait so copy to buffer
let mut buf = Vec::new(); let mut buf = Vec::new();
report_internal_error!(reader.read_to_end(&mut buf))?; reader.read_to_end(&mut buf).to_internal_error()?;
let tree = report_internal_error!(usvg::Tree::from_data(&buf, &Default::default()))?; let tree = usvg::Tree::from_data(&buf, &Default::default()).to_internal_error()?;
let size = tree.size(); let size = tree.size();
let mut pixmap = Pixmap::new(size.width() as u32, size.height() as u32) let mut pixmap = Pixmap::new(size.width() as u32, size.height() as u32)
.ok_or_else(|| create_error!(ImageProcessingFailed))?; .ok_or_else(|| create_error!(ImageProcessingFailed))?;
@@ -241,10 +237,11 @@ pub fn decode_image<R: Read + BufRead + Seek>(reader: &mut R, mime: &str) -> Res
)) ))
} }
// Check if we can read using image-rs crate // Check if we can read using image-rs crate
_ => report_internal_error!(report_internal_error!( _ => image::ImageReader::new(reader)
image::ImageReader::new(reader).with_guessed_format() .with_guessed_format()
)? .to_internal_error()?
.decode()), .decode()
.to_internal_error()
} }
} }

View File

@@ -12,12 +12,12 @@ use axum::{
}; };
use axum_typed_multipart::{FieldData, TryFromMultipart, TypedMultipart}; use axum_typed_multipart::{FieldData, TryFromMultipart, TypedMultipart};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use revolt_config::{config, report_internal_error}; use revolt_config::config;
use revolt_database::{iso8601_timestamp::Timestamp, Database, FileHash, Metadata, User}; use revolt_database::{iso8601_timestamp::Timestamp, Database, FileHash, Metadata, User};
use revolt_files::{ use revolt_files::{
create_thumbnail, decode_image, fetch_from_s3, upload_to_s3, AUTHENTICATION_TAG_SIZE_BYTES, create_thumbnail, decode_image, fetch_from_s3, upload_to_s3, AUTHENTICATION_TAG_SIZE_BYTES,
}; };
use revolt_result::{create_error, Error, Result}; use revolt_result::{create_error, Error, Result, ToRevoltError};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::Digest; use sha2::Digest;
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
@@ -181,7 +181,7 @@ async fn upload_file(
// Load file to memory // Load file to memory
let mut buf = Vec::<u8>::new(); let mut buf = Vec::<u8>::new();
report_internal_error!(file.contents.read_to_end(&mut buf))?; file.contents.read_to_end(&mut buf).to_internal_error()?;
// Take note of original file size // Take note of original file size
let original_file_size = buf.len(); let original_file_size = buf.len();

View File

@@ -1,7 +1,7 @@
use std::time::Duration; use std::time::Duration;
use revolt_config::{config, report_internal_error}; use revolt_config::config;
use revolt_result::Result; use revolt_result::{Result, ToRevoltError};
/// Initialise ClamAV /// Initialise ClamAV
pub async fn init() { pub async fn init() {
@@ -38,12 +38,12 @@ pub async fn is_malware(buf: &[u8]) -> Result<bool> {
if config.files.clamd_host.is_empty() { if config.files.clamd_host.is_empty() {
Ok(false) Ok(false)
} else { } else {
let scan_response = report_internal_error!(revolt_clamav_client::scan_buffer_tcp( let scan_response =
buf, revolt_clamav_client::scan_buffer_tcp(buf, config.files.clamd_host, None)
config.files.clamd_host, .to_internal_error()?;
None
))?;
report_internal_error!(revolt_clamav_client::clean(&scan_response)).map(|v| !v) revolt_clamav_client::clean(&scan_response)
.to_internal_error()
.map(|v| !v)
} }
} }

View File

@@ -2,9 +2,8 @@ use std::io::{Cursor, Read};
use exif::Reader; use exif::Reader;
use image::{ImageFormat, ImageReader}; use image::{ImageFormat, ImageReader};
use revolt_config::report_internal_error;
use revolt_database::Metadata; use revolt_database::Metadata;
use revolt_result::{create_error, Result}; use revolt_result::{create_error, Result, ToRevoltError};
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
use tokio::process::Command; use tokio::process::Command;
@@ -41,11 +40,11 @@ pub async fn strip_metadata(
let mut cursor = Cursor::new(buf); let mut cursor = Cursor::new(buf);
// Decode the image // Decode the image
let image = report_internal_error!(report_internal_error!(ImageReader::new( let image = ImageReader::new(&mut cursor)
&mut cursor .with_guessed_format()
) .to_internal_error()?
.with_guessed_format())? .decode()
.decode()); .to_internal_error()?;
// Reset read position // Reset read position
cursor.set_position(0); cursor.set_position(0);
@@ -66,15 +65,15 @@ pub async fn strip_metadata(
// Apply the EXIF rotation // Apply the EXIF rotation
// See https://jdhao.github.io/2019/07/31/image_rotation_exif_info/ // See https://jdhao.github.io/2019/07/31/image_rotation_exif_info/
report_internal_error!(match &rotation { match &rotation {
2 => image?.fliph(), 2 => image.fliph(),
3 => image?.rotate180(), 3 => image.rotate180(),
4 => image?.rotate180().fliph(), 4 => image.rotate180().fliph(),
5 => image?.rotate90().fliph(), 5 => image.rotate90().fliph(),
6 => image?.rotate90(), 6 => image.rotate90(),
7 => image?.rotate270().fliph(), 7 => image.rotate270().fliph(),
8 => image?.rotate270(), 8 => image.rotate270(),
_ => image?, _ => image,
} }
.write_to( .write_to(
&mut writer, &mut writer,
@@ -85,7 +84,7 @@ pub async fn strip_metadata(
"image/tiff" => ImageFormat::Tiff, "image/tiff" => ImageFormat::Tiff,
_ => todo!(), _ => todo!(),
}, },
))?; ).to_internal_error()?;
// Calculate dimensions after rotation. // Calculate dimensions after rotation.
let (width, height) = match &rotation { let (width, height) = match &rotation {
@@ -113,44 +112,43 @@ pub async fn strip_metadata(
}; };
// Temporary output file // Temporary output file
let mut out_file = report_internal_error!(NamedTempFile::new())?; let mut out_file = NamedTempFile::new().to_internal_error()?;
// Process the file with ffmpeg // Process the file with ffmpeg
report_internal_error!( Command::new("ffmpeg")
Command::new("ffmpeg") .args([
.args([ // Overwrite the temporary file
// Overwrite the temporary file "-y",
"-y", // Read original uploaded file
// Read original uploaded file "-i",
"-i", file.path().to_str().ok_or(create_error!(InternalError))?,
file.path().to_str().ok_or(create_error!(InternalError))?, // Strip any metadata
// Strip any metadata "-map_metadata",
"-map_metadata", "-1",
"-1", // Copy video / audio data to new file
// Copy video / audio data to new file "-c:v",
"-c:v", "copy",
"copy", "-c:a",
"-c:a", "copy",
"copy", // Select correct file format
// Select correct file format "-f",
"-f", ext,
ext, // Save to new temporary file
// Save to new temporary file out_file
out_file .path()
.path() .to_str()
.to_str() .ok_or(create_error!(InternalError))?,
.ok_or(create_error!(InternalError))?, ])
]) .output()
.output() .await
.await .to_internal_error()?;
)?;
// Probe the file again // Probe the file again
let metadata = crate::metadata::generate_metadata(&out_file, mime); let metadata = crate::metadata::generate_metadata(&out_file, mime);
// Read the file from disk // Read the file from disk
let mut buf = Vec::<u8>::new(); let mut buf = Vec::<u8>::new();
report_internal_error!(out_file.read_to_end(&mut buf))?; out_file.read_to_end(&mut buf).to_internal_error()?;
Ok((buf, metadata)) Ok((buf, metadata))
} }

View File

@@ -6,10 +6,9 @@ use reqwest::{
header::{self, CONTENT_TYPE}, header::{self, CONTENT_TYPE},
redirect, Client, Response, redirect, Client, Response,
}; };
use revolt_config::report_internal_error;
use revolt_files::{create_thumbnail, decode_image, image_size_vec, is_valid_image, video_size}; use revolt_files::{create_thumbnail, decode_image, image_size_vec, is_valid_image, video_size};
use revolt_models::v0::{Embed, Image, ImageSize, Video}; use revolt_models::v0::{Embed, Image, ImageSize, Video};
use revolt_result::{create_error, Error, Result}; use revolt_result::{create_error, Error, Result, ToRevoltError};
use std::{ use std::{
io::{Cursor, Write}, io::{Cursor, Write},
time::Duration, time::Duration,
@@ -76,7 +75,7 @@ impl Request {
let Request { response, mime } = Request::new(url).await?; let Request { response, mime } = Request::new(url).await?;
if matches!(mime.type_(), mime::IMAGE | mime::VIDEO) { if matches!(mime.type_(), mime::IMAGE | mime::VIDEO) {
let bytes = report_internal_error!(response.bytes().await); let bytes = response.bytes().await.to_internal_error();
let result = match bytes { let result = match bytes {
Ok(bytes) => { Ok(bytes) => {
@@ -100,8 +99,8 @@ impl Request {
)) ))
} }
} else { } else {
let mut file = report_internal_error!(tempfile::NamedTempFile::new())?; let mut file = tempfile::NamedTempFile::new().to_internal_error()?;
report_internal_error!(file.write_all(&bytes))?; file.write_all(&bytes).to_internal_error()?;
if video_size(&file).is_some() { if video_size(&file).is_some() {
Ok((mime.to_string(), bytes.to_vec())) Ok((mime.to_string(), bytes.to_vec()))
@@ -144,7 +143,7 @@ impl Request {
}; };
if let Some((width, height)) = image_size_vec( if let Some((width, height)) = image_size_vec(
&report_internal_error!(request.response.bytes().await)?, &request.response.bytes().await.to_internal_error()?,
request.mime.as_ref(), request.mime.as_ref(),
) { ) {
Ok(Some(Image { Ok(Some(Image {
@@ -181,10 +180,9 @@ impl Request {
} }
}; };
let mut file = report_internal_error!(tempfile::NamedTempFile::new())?; let mut file = tempfile::NamedTempFile::new().to_internal_error()?;
report_internal_error!( file.write_all(&response.bytes().await.to_internal_error()?)
file.write_all(&report_internal_error!(response.bytes().await)?) .to_internal_error()?;
)?;
if let Some((width, height)) = video_size(&file) { if let Some((width, height)) = video_size(&file) {
Ok(Some(Video { Ok(Some(Video {
@@ -230,7 +228,7 @@ impl Request {
let encoding = let encoding =
Encoding::for_label(encoding_name.as_bytes()).unwrap_or(&UTF_8_INIT); Encoding::for_label(encoding_name.as_bytes()).unwrap_or(&UTF_8_INIT);
let bytes = report_internal_error!(request.response.bytes().await)?; let bytes = request.response.bytes().await.to_internal_error()?;
let (text, _, _) = encoding.decode(&bytes); let (text, _, _) = encoding.decode(&bytes);
crate::website_embed::create_website_embed(&url, &text) crate::website_embed::create_website_embed(&url, &text)