chore: update routes to use utoipa

This commit is contained in:
Zomatree
2025-11-17 22:13:07 +00:00
parent ac60b2c795
commit 43c94b68b0
110 changed files with 891 additions and 231 deletions

View File

@@ -15,7 +15,7 @@ use crate::{CoalescionServiceConfig, Error};
#[derive(Debug, Clone)]
#[allow(clippy::type_complexity)]
/// # Coalescion service
/// Coalescion service
///
/// See module description for example usage.
pub struct CoalescionService<Id: Hash + Clone + Eq> {

View File

@@ -25,6 +25,10 @@ pub use mongodb;
#[macro_use]
extern crate bson;
#[cfg(feature = "utoipa")]
#[macro_use]
extern crate utoipa;
#[cfg(not(feature = "async-std-runtime"))]
compile_error!("async-std-runtime feature must be enabled.");

View File

@@ -15,7 +15,7 @@ use serde_json::json;
use ulid::Ulid;
auto_derived_partial!(
/// # User
/// User
pub struct User {
/// Unique Id
#[serde(rename = "_id")]

View File

@@ -10,16 +10,16 @@ use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct IdempotencyKey {
key: String,
}
#[cfg_attr(feature = "utoipa", derive(IntoParams))]
#[cfg_attr(feature = "utoipa", into_params(names("Idempotency-Key"), parameter_in=Header))]
pub struct IdempotencyKey(String);
static TOKEN_CACHE: Lazy<Mutex<lru::LruCache<String, ()>>> =
Lazy::new(|| Mutex::new(lru::LruCache::new(NonZeroUsize::new(1000).unwrap())));
impl IdempotencyKey {
pub fn unchecked_from_string(key: String) -> Self {
Self { key }
Self(key)
}
// Backwards compatibility.
@@ -32,14 +32,14 @@ impl IdempotencyKey {
}
cache.put(v.clone(), ());
self.key = v;
self.0 = v;
}
Ok(())
}
pub fn into_key(self) -> String {
self.key
self.0
}
}
@@ -110,18 +110,16 @@ impl<'r> FromRequest<'r> for IdempotencyKey {
));
}
let idempotency = IdempotencyKey { key };
let idempotency = IdempotencyKey(key);
let mut cache = TOKEN_CACHE.lock().await;
if cache.get(&idempotency.key).is_some() {
if cache.get(&idempotency.0).is_some() {
return Outcome::Error((Status::Conflict, create_error!(DuplicateNonce)));
}
cache.put(idempotency.key.clone(), ());
cache.put(idempotency.0.clone(), ());
return Outcome::Success(idempotency);
}
Outcome::Success(IdempotencyKey {
key: ulid::Ulid::new().to_string(),
})
Outcome::Success(IdempotencyKey(ulid::Ulid::new().to_string()))
}
}

View File

@@ -283,6 +283,7 @@ auto_derived!(
/// Options when deleting a channel
#[cfg_attr(feature = "rocket", derive(FromForm))]
#[cfg_attr(feature = "utoipa", derive(IntoParams))]
pub struct OptionsChannelDelete {
/// Whether to not send a leave message
pub leave_silently: Option<bool>,

View File

@@ -1,5 +1,5 @@
auto_derived!(
/// # hCaptcha Configuration
/// hCaptcha Configuration
pub struct CaptchaFeature {
/// Whether captcha is enabled
pub enabled: bool,
@@ -7,7 +7,7 @@ auto_derived!(
pub key: String,
}
/// # Generic Service Configuration
/// Generic Service Configuration
pub struct Feature {
/// Whether the service is enabled
pub enabled: bool,
@@ -15,7 +15,7 @@ auto_derived!(
pub url: String,
}
/// # Voice Server Configuration
/// Voice Server Configuration
pub struct VoiceFeature {
/// Whether voice is enabled
pub enabled: bool,
@@ -25,7 +25,7 @@ auto_derived!(
pub ws: String,
}
/// # Feature Configuration
/// Feature Configuration
pub struct RevoltFeatures {
/// hCaptcha configuration
pub captcha: CaptchaFeature,
@@ -41,7 +41,7 @@ auto_derived!(
pub voso: VoiceFeature,
}
/// # Build Information
/// Build Information
pub struct BuildInformation {
/// Commit Hash
pub commit_sha: String,
@@ -55,7 +55,7 @@ auto_derived!(
pub timestamp: String,
}
/// # Server Configuration
/// Server Configuration
pub struct RevoltConfig {
/// Revolt API Version
pub revolt: String,
@@ -70,4 +70,4 @@ auto_derived!(
/// Build information
pub build: BuildInformation,
}
);
);

View File

@@ -279,6 +279,7 @@ auto_derived!(
/// Options for querying messages
#[cfg_attr(feature = "validator", derive(Validate))]
#[cfg_attr(feature = "rocket", derive(FromForm))]
#[cfg_attr(feature = "utoipa", derive(IntoParams))]
pub struct OptionsQueryMessages {
/// Maximum number of messages to fetch
///
@@ -357,6 +358,7 @@ auto_derived!(
/// Options for removing reaction
#[cfg_attr(feature = "rocket", derive(FromForm))]
#[cfg_attr(feature = "utoipa", derive(IntoParams))]
pub struct OptionsUnreact {
/// Remove a specific user's reaction
pub user_id: Option<String>,

View File

@@ -99,6 +99,7 @@ auto_derived!(
/// Options for fetching all members
#[cfg_attr(feature = "rocket", derive(FromForm))]
#[cfg_attr(feature = "utoipa", derive(IntoParams))]
pub struct OptionsFetchAllMembers {
/// Whether to exclude offline users
pub exclude_offline: Option<bool>,

View File

@@ -198,6 +198,7 @@ auto_derived!(
/// Options when fetching server
#[cfg_attr(feature = "rocket", derive(FromForm))]
#[cfg_attr(feature = "utoipa", derive(IntoParams))]
pub struct OptionsFetchServer {
/// Whether to include channels
pub include_channels: Option<bool>,
@@ -284,6 +285,7 @@ auto_derived!(
/// Options when leaving a server
#[cfg_attr(feature = "rocket", derive(FromForm))]
#[cfg_attr(feature = "utoipa", derive(IntoParams))]
pub struct OptionsServerDelete {
/// Whether to not send a leave message
pub leave_silently: Option<bool>,

View File

@@ -17,6 +17,7 @@ auto_derived!(
/// Additional options for inserting settings
#[cfg_attr(feature = "rocket", derive(FromForm))]
#[cfg_attr(feature = "utoipa", derive(IntoParams))]
pub struct OptionsSetSettings {
/// Timestamp of settings change.
///

View File

@@ -5,8 +5,9 @@ use std::fmt::Display;
extern crate serde;
#[cfg(feature = "utoipa")]
#[macro_use]
extern crate utoipa;
mod utoipa_impl;
#[cfg(feature = "utoipa")]
pub use crate::utoipa_impl::*;
#[cfg(feature = "rocket")]
pub mod rocket;
@@ -19,7 +20,7 @@ pub type Result<T, E = Error> = std::result::Result<T, E>;
/// Error information
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone)]
pub struct Error {
/// Type of error and additional information
@@ -41,7 +42,7 @@ impl std::error::Error for Error {}
/// Possible error types
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(tag = "type"))]
#[cfg_attr(feature = "utoipa", derive(ToSchema))]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[derive(Debug, Clone)]
pub enum ErrorType {
/// This error was not labeled :(

View File

@@ -0,0 +1,52 @@
use utoipa::{Modify, openapi::{Content, OpenApi, Ref, RefOr, ResponseBuilder}};
pub struct ErrorAddon;
impl Modify for ErrorAddon {
fn modify(&self, utoipa: &mut OpenApi) {
let response = ResponseBuilder::new()
.description("An error occurred")
.content(
"application/json",
Content::new(Some(RefOr::Ref(Ref::from_schema_name("Error")))),
)
.build();
for path in utoipa.paths.paths.values_mut() {
if let Some(route) = path.get.as_mut() {
route
.responses
.responses
.insert("default".to_string(), RefOr::T(response.clone()));
};
if let Some(route) = path.delete.as_mut() {
route
.responses
.responses
.insert("default".to_string(), RefOr::T(response.clone()));
};
if let Some(route) = path.patch.as_mut() {
route
.responses
.responses
.insert("default".to_string(), RefOr::T(response.clone()));
};
if let Some(route) = path.post.as_mut() {
route
.responses
.responses
.insert("default".to_string(), RefOr::T(response.clone()));
};
if let Some(route) = path.put.as_mut() {
route
.responses
.responses
.insert("default".to_string(), RefOr::T(response.clone()));
};
}
}
}