chore: update routes to use utoipa
This commit is contained in:
@@ -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> {
|
||||
|
||||
@@ -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.");
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ use serde_json::json;
|
||||
use ulid::Ulid;
|
||||
|
||||
auto_derived_partial!(
|
||||
/// # User
|
||||
/// User
|
||||
pub struct User {
|
||||
/// Unique Id
|
||||
#[serde(rename = "_id")]
|
||||
|
||||
@@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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>,
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
|
||||
@@ -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 :(
|
||||
|
||||
52
crates/core/result/src/utoipa_impl.rs
Normal file
52
crates/core/result/src/utoipa_impl.rs
Normal 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()));
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user