mirror of
https://gitlab.com/msrd0/gotham-restful.git
synced 2025-02-22 20:52:27 +00:00
add optional fs support
This commit is contained in:
parent
e013af8e18
commit
66e9ce96b9
4 changed files with 96 additions and 11 deletions
|
@ -32,6 +32,7 @@ mime = "0.3.16"
|
|||
openapiv3 = { version = "0.3", optional = true }
|
||||
serde = { version = "1.0.106", features = ["derive"] }
|
||||
serde_json = "1.0.51"
|
||||
tokio = { version = "0.2.20", optional = true }
|
||||
thiserror = "1.0.15"
|
||||
uuid = { version = ">= 0.1, < 0.9", optional = true }
|
||||
|
||||
|
@ -40,8 +41,9 @@ futures-executor = "0.3.4"
|
|||
paste = "0.1.10"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
default = ["fs"]
|
||||
auth = ["gotham_restful_derive/auth", "base64", "cookie", "jsonwebtoken"]
|
||||
fs = ["tokio", "tokio/fs"]
|
||||
errorlog = []
|
||||
database = ["gotham_restful_derive/database", "gotham_middleware_diesel"]
|
||||
openapi = ["gotham_restful_derive/openapi", "indexmap", "openapiv3"]
|
||||
|
|
78
gotham_restful/src/fs.rs
Normal file
78
gotham_restful/src/fs.rs
Normal file
|
@ -0,0 +1,78 @@
|
|||
use crate::{
|
||||
result::{errorlog, into_response_helper, ResourceError},
|
||||
OpenapiSchema, ResourceResult, Response
|
||||
};
|
||||
use futures_util::future::{FutureExt, TryFutureExt};
|
||||
use gotham::hyper::StatusCode;
|
||||
use mime::Mime;
|
||||
use openapiv3::{SchemaKind, StringFormat, StringType, Type, VariantOrUnknownOrEmpty};
|
||||
use std::{
|
||||
future::Future,
|
||||
path::PathBuf,
|
||||
pin::Pin
|
||||
};
|
||||
use thiserror::Error;
|
||||
|
||||
pub struct File
|
||||
{
|
||||
path : PathBuf,
|
||||
content_type : Option<Mime>
|
||||
}
|
||||
|
||||
impl ResourceResult for File
|
||||
{
|
||||
type Err = tokio::io::Error;
|
||||
|
||||
fn into_response(self) -> Pin<Box<dyn Future<Output = Result<Response, Self::Err>> + Send>>
|
||||
{
|
||||
async move {
|
||||
let data = tokio::fs::read(self.path).await?;
|
||||
let res = Response::new(StatusCode::OK, data, self.content_type);
|
||||
Ok(res)
|
||||
}.boxed()
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
fn schema() -> OpenapiSchema
|
||||
{
|
||||
OpenapiSchema::new(SchemaKind::Type(Type::String(StringType {
|
||||
format: VariantOrUnknownOrEmpty::Item(StringFormat::Binary),
|
||||
..Default::default()
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum IoOrJsonError
|
||||
{
|
||||
#[error("{0}")]
|
||||
IoError(#[from] tokio::io::Error),
|
||||
#[error("{0}")]
|
||||
JsonError(#[from] serde_json::Error)
|
||||
}
|
||||
|
||||
impl<E : std::error::Error + Send + 'static> ResourceResult for Result<File, E>
|
||||
{
|
||||
type Err = IoOrJsonError;
|
||||
|
||||
fn into_response(self) -> Pin<Box<dyn Future<Output = Result<Response, IoOrJsonError>> + Send>>
|
||||
{
|
||||
match self {
|
||||
Ok(f) => f.into_response().map_err(|e| e.into()).boxed(),
|
||||
Err(e) => into_response_helper(|| {
|
||||
errorlog(&e);
|
||||
let err : ResourceError = e.into();
|
||||
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
fn schema() -> OpenapiSchema
|
||||
{
|
||||
OpenapiSchema::new(SchemaKind::Type(Type::String(StringType {
|
||||
format: VariantOrUnknownOrEmpty::Item(StringFormat::Binary),
|
||||
..Default::default()
|
||||
})))
|
||||
}
|
||||
}
|
|
@ -152,6 +152,11 @@ pub use auth::{
|
|||
StaticAuthHandler
|
||||
};
|
||||
|
||||
#[cfg(feature = "fs")]
|
||||
mod fs;
|
||||
#[cfg(feature = "fs")]
|
||||
pub use fs::File;
|
||||
|
||||
pub mod matcher;
|
||||
|
||||
#[cfg(feature = "openapi")]
|
||||
|
|
|
@ -132,7 +132,7 @@ impl<T : ToString> From<T> for ResourceError
|
|||
}
|
||||
}
|
||||
|
||||
fn into_response_helper<Err, F>(create_response : F) -> Pin<Box<dyn Future<Output = Result<Response, Err>> + Send>>
|
||||
pub fn into_response_helper<Err, F>(create_response : F) -> Pin<Box<dyn Future<Output = Result<Response, Err>> + Send>>
|
||||
where
|
||||
Err : Send + 'static,
|
||||
F : FnOnce() -> Result<Response, Err>
|
||||
|
@ -142,13 +142,13 @@ where
|
|||
}
|
||||
|
||||
#[cfg(feature = "errorlog")]
|
||||
fn errorlog<E : std::fmt::Display>(e : E)
|
||||
pub fn errorlog<E : std::fmt::Display>(e : E)
|
||||
{
|
||||
error!("The handler encountered an error: {}", e);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "errorlog"))]
|
||||
fn errorlog<E>(_e : E) {}
|
||||
pub fn errorlog<E>(_e : E) {}
|
||||
|
||||
impl<R : ResponseBody, E : Error> ResourceResult for Result<R, E>
|
||||
where
|
||||
|
@ -413,13 +413,11 @@ impl<T : ResourceResult<Err = SerdeJsonError>, E : Error> ResourceResult for Res
|
|||
{
|
||||
match self {
|
||||
Ok(r) => r.into_response(),
|
||||
Err(e) => {
|
||||
into_response_helper(|| {
|
||||
errorlog(&e);
|
||||
let err : ResourceError = e.into();
|
||||
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
||||
})
|
||||
}
|
||||
Err(e) => into_response_helper(|| {
|
||||
errorlog(&e);
|
||||
let err : ResourceError = e.into();
|
||||
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,6 +512,7 @@ where
|
|||
match self {
|
||||
Ok(nc) => nc.into_response(),
|
||||
Err(e) => into_response_helper(|| {
|
||||
errorlog(&e);
|
||||
let err : ResourceError = e.into();
|
||||
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
||||
})
|
||||
|
@ -603,6 +602,7 @@ where
|
|||
match self {
|
||||
Ok(raw) => raw.into_response(),
|
||||
Err(e) => into_response_helper(|| {
|
||||
errorlog(&e);
|
||||
let err : ResourceError = e.into();
|
||||
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue