mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-13 21:17:05 +00:00
chore: switch to method chaining over macro
This commit is contained in:
@@ -14,7 +14,6 @@ use futures::{
|
||||
FutureExt, SinkExt, StreamExt, TryStreamExt,
|
||||
};
|
||||
use redis_kiss::{PayloadType, REDIS_PAYLOAD_TYPE, REDIS_URI};
|
||||
use revolt_config::report_internal_error;
|
||||
use revolt_database::{
|
||||
events::{client::EventV1, server::ClientMessage},
|
||||
iso8601_timestamp::Timestamp,
|
||||
@@ -27,7 +26,7 @@ use async_std::{
|
||||
sync::{Mutex, RwLock},
|
||||
task::spawn,
|
||||
};
|
||||
use revolt_result::create_error;
|
||||
use revolt_result::{create_error, ToRevoltError};
|
||||
use sentry::Level;
|
||||
|
||||
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();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Download required data to local cache and send Ready payload.
|
||||
let ready_payload = match report_internal_error!(
|
||||
state
|
||||
let ready_payload = match state
|
||||
.generate_ready_payload(db, config.get_ready_payload_fields())
|
||||
.await
|
||||
) {
|
||||
.to_internal_error()
|
||||
{
|
||||
Ok(ready_payload) => ready_payload,
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -219,14 +218,15 @@ async fn listener(
|
||||
write: &Mutex<WsWriter>,
|
||||
) {
|
||||
let redis_config = RedisConfig::from_url(&REDIS_URI).unwrap();
|
||||
let subscriber = match report_internal_error!(
|
||||
fred::types::Builder::from_config(redis_config).build_subscriber_client()
|
||||
) {
|
||||
let subscriber = match fred::types::Builder::from_config(redis_config)
|
||||
.build_subscriber_client()
|
||||
.to_internal_error()
|
||||
{
|
||||
Ok(subscriber) => subscriber,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
if report_internal_error!(subscriber.init().await).is_err() {
|
||||
if subscriber.init().await.to_internal_error().is_err() {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -249,13 +249,13 @@ async fn listener(
|
||||
// Check for state changes for subscriptions.
|
||||
match state.apply_state().await {
|
||||
SubscriptionStateChange::Reset => {
|
||||
if report_internal_error!(subscriber.unsubscribe_all().await).is_err() {
|
||||
if subscriber.unsubscribe_all().await.to_internal_error().is_err() {
|
||||
break 'out;
|
||||
}
|
||||
|
||||
let subscribed = state.subscribed.read().await;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -268,7 +268,7 @@ async fn listener(
|
||||
#[cfg(debug_assertions)]
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -277,7 +277,7 @@ async fn listener(
|
||||
#[cfg(debug_assertions)]
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -302,7 +302,7 @@ async fn listener(
|
||||
_ = t2 => {},
|
||||
message = t1 => {
|
||||
// Handle incoming events.
|
||||
let message = match report_internal_error!(message) {
|
||||
let message = match message.to_internal_error() {
|
||||
Ok(message) => message,
|
||||
Err(_) => break 'out
|
||||
};
|
||||
@@ -311,15 +311,15 @@ async fn listener(
|
||||
PayloadType::Json => message
|
||||
.value
|
||||
.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
|
||||
.value
|
||||
.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
|
||||
.value
|
||||
.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 {
|
||||
@@ -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)]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use bson::to_document;
|
||||
use bson::Document;
|
||||
use revolt_config::report_internal_error;
|
||||
use revolt_result::Result;
|
||||
use revolt_result::ToRevoltError;
|
||||
|
||||
use crate::File;
|
||||
use crate::FileUsedFor;
|
||||
@@ -106,7 +106,7 @@ impl AbstractAttachments for MongoDb {
|
||||
},
|
||||
doc! {
|
||||
"$set": {
|
||||
"used_for": report_internal_error!(to_document(&used_for))?,
|
||||
"used_for": to_document(&used_for).to_internal_error()?,
|
||||
"uploader_id": uploader_id
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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
|
||||
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
|
||||
let mut buf = vec![];
|
||||
while let Some(bytes) = obj.body.next().await {
|
||||
let data = report_internal_error!(bytes)?;
|
||||
report_internal_error!(buf.write_all(&data))?;
|
||||
buf.write_all(&bytes.to_internal_error()?).to_internal_error()?;
|
||||
// is there a more efficient way to do this?
|
||||
// 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()?;
|
||||
|
||||
// Upload the file to remote
|
||||
report_internal_error!(
|
||||
client
|
||||
.put_object()
|
||||
.bucket(bucket_id)
|
||||
.key(path)
|
||||
.body(buf.into())
|
||||
.send()
|
||||
.await
|
||||
)?;
|
||||
client
|
||||
.put_object()
|
||||
.bucket(bucket_id)
|
||||
.key(path)
|
||||
.body(buf.into())
|
||||
.send()
|
||||
.await
|
||||
.to_internal_error()?;
|
||||
|
||||
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 client = create_client(config.files.s3);
|
||||
|
||||
report_internal_error!(
|
||||
client
|
||||
.delete_object()
|
||||
.bucket(bucket_id)
|
||||
.key(path)
|
||||
.send()
|
||||
.await
|
||||
)?;
|
||||
client
|
||||
.delete_object()
|
||||
.bucket(bucket_id)
|
||||
.key(path)
|
||||
.send()
|
||||
.await
|
||||
.to_internal_error()?;
|
||||
|
||||
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)> {
|
||||
match mime {
|
||||
"image/svg+xml" => {
|
||||
let tree =
|
||||
report_internal_error!(usvg::Tree::from_data(v, &Default::default())).ok()?;
|
||||
let tree = usvg::Tree::from_data(v, &Default::default()).to_internal_error().ok()?;
|
||||
|
||||
let size = tree.size();
|
||||
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" => {
|
||||
// usvg doesn't support Read trait so copy to buffer
|
||||
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 mut pixmap = Pixmap::new(size.width() as u32, size.height() as u32)
|
||||
.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
|
||||
_ => report_internal_error!(report_internal_error!(
|
||||
image::ImageReader::new(reader).with_guessed_format()
|
||||
)?
|
||||
.decode()),
|
||||
_ => image::ImageReader::new(reader)
|
||||
.with_guessed_format()
|
||||
.to_internal_error()?
|
||||
.decode()
|
||||
.to_internal_error()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ use axum::{
|
||||
};
|
||||
use axum_typed_multipart::{FieldData, TryFromMultipart, TypedMultipart};
|
||||
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_files::{
|
||||
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 sha2::Digest;
|
||||
use tempfile::NamedTempFile;
|
||||
@@ -181,7 +181,7 @@ async fn upload_file(
|
||||
|
||||
// Load file to memory
|
||||
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
|
||||
let original_file_size = buf.len();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use revolt_config::{config, report_internal_error};
|
||||
use revolt_result::Result;
|
||||
use revolt_config::config;
|
||||
use revolt_result::{Result, ToRevoltError};
|
||||
|
||||
/// Initialise ClamAV
|
||||
pub async fn init() {
|
||||
@@ -38,12 +38,12 @@ pub async fn is_malware(buf: &[u8]) -> Result<bool> {
|
||||
if config.files.clamd_host.is_empty() {
|
||||
Ok(false)
|
||||
} else {
|
||||
let scan_response = report_internal_error!(revolt_clamav_client::scan_buffer_tcp(
|
||||
buf,
|
||||
config.files.clamd_host,
|
||||
None
|
||||
))?;
|
||||
let scan_response =
|
||||
revolt_clamav_client::scan_buffer_tcp(buf, config.files.clamd_host, None)
|
||||
.to_internal_error()?;
|
||||
|
||||
report_internal_error!(revolt_clamav_client::clean(&scan_response)).map(|v| !v)
|
||||
revolt_clamav_client::clean(&scan_response)
|
||||
.to_internal_error()
|
||||
.map(|v| !v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,8 @@ use std::io::{Cursor, Read};
|
||||
|
||||
use exif::Reader;
|
||||
use image::{ImageFormat, ImageReader};
|
||||
use revolt_config::report_internal_error;
|
||||
use revolt_database::Metadata;
|
||||
use revolt_result::{create_error, Result};
|
||||
use revolt_result::{create_error, Result, ToRevoltError};
|
||||
use tempfile::NamedTempFile;
|
||||
use tokio::process::Command;
|
||||
|
||||
@@ -41,11 +40,11 @@ pub async fn strip_metadata(
|
||||
let mut cursor = Cursor::new(buf);
|
||||
|
||||
// Decode the image
|
||||
let image = report_internal_error!(report_internal_error!(ImageReader::new(
|
||||
&mut cursor
|
||||
)
|
||||
.with_guessed_format())?
|
||||
.decode());
|
||||
let image = ImageReader::new(&mut cursor)
|
||||
.with_guessed_format()
|
||||
.to_internal_error()?
|
||||
.decode()
|
||||
.to_internal_error()?;
|
||||
|
||||
// Reset read position
|
||||
cursor.set_position(0);
|
||||
@@ -66,15 +65,15 @@ pub async fn strip_metadata(
|
||||
|
||||
// Apply the EXIF rotation
|
||||
// See https://jdhao.github.io/2019/07/31/image_rotation_exif_info/
|
||||
report_internal_error!(match &rotation {
|
||||
2 => image?.fliph(),
|
||||
3 => image?.rotate180(),
|
||||
4 => image?.rotate180().fliph(),
|
||||
5 => image?.rotate90().fliph(),
|
||||
6 => image?.rotate90(),
|
||||
7 => image?.rotate270().fliph(),
|
||||
8 => image?.rotate270(),
|
||||
_ => image?,
|
||||
match &rotation {
|
||||
2 => image.fliph(),
|
||||
3 => image.rotate180(),
|
||||
4 => image.rotate180().fliph(),
|
||||
5 => image.rotate90().fliph(),
|
||||
6 => image.rotate90(),
|
||||
7 => image.rotate270().fliph(),
|
||||
8 => image.rotate270(),
|
||||
_ => image,
|
||||
}
|
||||
.write_to(
|
||||
&mut writer,
|
||||
@@ -85,7 +84,7 @@ pub async fn strip_metadata(
|
||||
"image/tiff" => ImageFormat::Tiff,
|
||||
_ => todo!(),
|
||||
},
|
||||
))?;
|
||||
).to_internal_error()?;
|
||||
|
||||
// Calculate dimensions after rotation.
|
||||
let (width, height) = match &rotation {
|
||||
@@ -113,44 +112,43 @@ pub async fn strip_metadata(
|
||||
};
|
||||
|
||||
// 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
|
||||
report_internal_error!(
|
||||
Command::new("ffmpeg")
|
||||
.args([
|
||||
// Overwrite the temporary file
|
||||
"-y",
|
||||
// Read original uploaded file
|
||||
"-i",
|
||||
file.path().to_str().ok_or(create_error!(InternalError))?,
|
||||
// Strip any metadata
|
||||
"-map_metadata",
|
||||
"-1",
|
||||
// Copy video / audio data to new file
|
||||
"-c:v",
|
||||
"copy",
|
||||
"-c:a",
|
||||
"copy",
|
||||
// Select correct file format
|
||||
"-f",
|
||||
ext,
|
||||
// Save to new temporary file
|
||||
out_file
|
||||
.path()
|
||||
.to_str()
|
||||
.ok_or(create_error!(InternalError))?,
|
||||
])
|
||||
.output()
|
||||
.await
|
||||
)?;
|
||||
Command::new("ffmpeg")
|
||||
.args([
|
||||
// Overwrite the temporary file
|
||||
"-y",
|
||||
// Read original uploaded file
|
||||
"-i",
|
||||
file.path().to_str().ok_or(create_error!(InternalError))?,
|
||||
// Strip any metadata
|
||||
"-map_metadata",
|
||||
"-1",
|
||||
// Copy video / audio data to new file
|
||||
"-c:v",
|
||||
"copy",
|
||||
"-c:a",
|
||||
"copy",
|
||||
// Select correct file format
|
||||
"-f",
|
||||
ext,
|
||||
// Save to new temporary file
|
||||
out_file
|
||||
.path()
|
||||
.to_str()
|
||||
.ok_or(create_error!(InternalError))?,
|
||||
])
|
||||
.output()
|
||||
.await
|
||||
.to_internal_error()?;
|
||||
|
||||
// Probe the file again
|
||||
let metadata = crate::metadata::generate_metadata(&out_file, mime);
|
||||
|
||||
// Read the file from disk
|
||||
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))
|
||||
}
|
||||
|
||||
@@ -6,10 +6,9 @@ use reqwest::{
|
||||
header::{self, CONTENT_TYPE},
|
||||
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_models::v0::{Embed, Image, ImageSize, Video};
|
||||
use revolt_result::{create_error, Error, Result};
|
||||
use revolt_result::{create_error, Error, Result, ToRevoltError};
|
||||
use std::{
|
||||
io::{Cursor, Write},
|
||||
time::Duration,
|
||||
@@ -76,7 +75,7 @@ impl Request {
|
||||
let Request { response, mime } = Request::new(url).await?;
|
||||
|
||||
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 {
|
||||
Ok(bytes) => {
|
||||
@@ -100,8 +99,8 @@ impl Request {
|
||||
))
|
||||
}
|
||||
} else {
|
||||
let mut file = report_internal_error!(tempfile::NamedTempFile::new())?;
|
||||
report_internal_error!(file.write_all(&bytes))?;
|
||||
let mut file = tempfile::NamedTempFile::new().to_internal_error()?;
|
||||
file.write_all(&bytes).to_internal_error()?;
|
||||
|
||||
if video_size(&file).is_some() {
|
||||
Ok((mime.to_string(), bytes.to_vec()))
|
||||
@@ -144,7 +143,7 @@ impl Request {
|
||||
};
|
||||
|
||||
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(),
|
||||
) {
|
||||
Ok(Some(Image {
|
||||
@@ -181,10 +180,9 @@ impl Request {
|
||||
}
|
||||
};
|
||||
|
||||
let mut file = report_internal_error!(tempfile::NamedTempFile::new())?;
|
||||
report_internal_error!(
|
||||
file.write_all(&report_internal_error!(response.bytes().await)?)
|
||||
)?;
|
||||
let mut file = tempfile::NamedTempFile::new().to_internal_error()?;
|
||||
file.write_all(&response.bytes().await.to_internal_error()?)
|
||||
.to_internal_error()?;
|
||||
|
||||
if let Some((width, height)) = video_size(&file) {
|
||||
Ok(Some(Video {
|
||||
@@ -230,7 +228,7 @@ impl Request {
|
||||
let encoding =
|
||||
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);
|
||||
|
||||
crate::website_embed::create_website_embed(&url, &text)
|
||||
|
||||
Reference in New Issue
Block a user