feat: Chat request implementation #14
3 changed files with 143 additions and 0 deletions
|
@ -30,6 +30,7 @@ mod extensions;
|
|||
mod macros;
|
||||
mod middlewares;
|
||||
mod nonce;
|
||||
mod parameters;
|
||||
mod routes;
|
||||
mod schemas;
|
||||
mod utils;
|
||||
|
|
21
crates/oxidetalis/src/parameters/mod.rs
Normal file
21
crates/oxidetalis/src/parameters/mod.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// OxideTalis Messaging Protocol homeserver implementation
|
||||
// Copyright (C) 2024 OxideTalis Developers <otmp@4rs.nl>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://gnu.org/licenses/agpl-3.0>.
|
||||
|
||||
//! Set of route parameters for the API
|
||||
|
||||
mod pagination;
|
||||
|
||||
pub use pagination::*;
|
121
crates/oxidetalis/src/parameters/pagination.rs
Normal file
121
crates/oxidetalis/src/parameters/pagination.rs
Normal file
|
@ -0,0 +1,121 @@
|
|||
// OxideTalis Messaging Protocol homeserver implementation
|
||||
// Copyright (C) 2024 OxideTalis Developers <otmp@4rs.nl>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://gnu.org/licenses/agpl-3.0>.
|
||||
|
||||
//! Pagination parameters for the API
|
||||
|
||||
use std::{
|
||||
fmt,
|
||||
num::{NonZeroU32, NonZeroU8},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use salvo::{
|
||||
extract::Metadata as ExtractMetadata,
|
||||
oapi::{
|
||||
Components as OapiComponents,
|
||||
Object,
|
||||
Parameter,
|
||||
ParameterIn,
|
||||
Parameters,
|
||||
SchemaType,
|
||||
ToParameters,
|
||||
},
|
||||
Extractible,
|
||||
Request,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
use crate::routes::{ApiError, ApiResult};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Pagination {
|
||||
awiteb marked this conversation as resolved
|
||||
/// The page number of the result
|
||||
pub page: NonZeroU32,
|
||||
/// The page size
|
||||
pub page_size: NonZeroU8,
|
||||
}
|
||||
|
||||
impl<'ex> Extractible<'ex> for Pagination {
|
||||
fn metadata() -> &'ex ExtractMetadata {
|
||||
static METADATA: ExtractMetadata = ExtractMetadata::new("");
|
||||
&METADATA
|
||||
}
|
||||
|
||||
#[allow(refining_impl_trait)]
|
||||
async fn extract(req: &'ex mut Request) -> ApiResult<Self> {
|
||||
let page = extract_query(req, "page", NonZeroU32::new(1).expect("is non-zero"))?;
|
||||
let page_size = extract_query(req, "page_size", NonZeroU8::new(10).expect("is non-zero"))?;
|
||||
|
||||
Ok(Self { page, page_size })
|
||||
}
|
||||
|
||||
#[allow(refining_impl_trait)]
|
||||
async fn extract_with_arg(req: &'ex mut Request, _arg: &str) -> ApiResult<Self> {
|
||||
Self::extract(req).await
|
||||
}
|
||||
}
|
||||
|
||||
impl ToParameters<'_> for Pagination {
|
||||
fn to_parameters(_components: &mut OapiComponents) -> Parameters {
|
||||
Parameters::new()
|
||||
.parameter(create_parameter(
|
||||
"page",
|
||||
"Page number, starting from 1",
|
||||
1,
|
||||
f64::from(u32::MAX),
|
||||
))
|
||||
.parameter(create_parameter(
|
||||
"page_size",
|
||||
"How many items per page, starting from 1",
|
||||
10,
|
||||
f64::from(u8::MAX),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract a query parameter from the request
|
||||
fn extract_query<T: FromStr>(req: &Request, name: &str, default_value: T) -> ApiResult<T>
|
||||
where
|
||||
<T as FromStr>::Err: fmt::Display,
|
||||
{
|
||||
Ok(req
|
||||
.queries()
|
||||
.get(name)
|
||||
.map(|p| p.parse::<T>())
|
||||
.transpose()
|
||||
.map_err(|err| ApiError::Querys(format!("Invalid value for `{name}` query ({err})")))?
|
||||
.unwrap_or(default_value))
|
||||
}
|
||||
|
||||
/// Create a parameter for the pagination
|
||||
fn create_parameter(name: &str, description: &str, default: usize, max: f64) -> Parameter {
|
||||
Parameter::new(name)
|
||||
.parameter_in(ParameterIn::Query)
|
||||
.required(false)
|
||||
.description(description)
|
||||
.example(json!(default))
|
||||
.schema(
|
||||
Object::new()
|
||||
.name(name)
|
||||
.description(description)
|
||||
.schema_type(SchemaType::Integer)
|
||||
.default_value(json!(default))
|
||||
.example(json!(default))
|
||||
.maximum(max)
|
||||
.minimum(1.0)
|
||||
.read_only(true),
|
||||
)
|
||||
}
|
Loading…
Reference in a new issue
We can add
EndpointArgRegister
implementation and thus we can use it in the arg directlyIf we go with this, we can also use
ToParameters
macro to generate the implementation.The issue with it is that it doesn't use
ApiError
, but if we are using it as a paremeter,salvo
will handle the error reportingI'll see it, the reason why I don't put it as an argument, is because
Salvo ask me to implement
ToSchema
to it.As I see, Salvo want it as one parameter, but the pagination
is two parameters. I'll see
Ok, I get it. It ask me to implement
ToSchema
because of thisSo I can just implement the
EndpointArgRegister
trait and not usingQueryParam
.Thank you @Amjad50