mirror of
https://gitlab.com/msrd0/gotham-restful.git
synced 2025-02-23 13:02:28 +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 }
|
openapiv3 = { version = "0.3", optional = true }
|
||||||
serde = { version = "1.0.106", features = ["derive"] }
|
serde = { version = "1.0.106", features = ["derive"] }
|
||||||
serde_json = "1.0.51"
|
serde_json = "1.0.51"
|
||||||
|
tokio = { version = "0.2.20", optional = true }
|
||||||
thiserror = "1.0.15"
|
thiserror = "1.0.15"
|
||||||
uuid = { version = ">= 0.1, < 0.9", optional = true }
|
uuid = { version = ">= 0.1, < 0.9", optional = true }
|
||||||
|
|
||||||
|
@ -40,8 +41,9 @@ futures-executor = "0.3.4"
|
||||||
paste = "0.1.10"
|
paste = "0.1.10"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = ["fs"]
|
||||||
auth = ["gotham_restful_derive/auth", "base64", "cookie", "jsonwebtoken"]
|
auth = ["gotham_restful_derive/auth", "base64", "cookie", "jsonwebtoken"]
|
||||||
|
fs = ["tokio", "tokio/fs"]
|
||||||
errorlog = []
|
errorlog = []
|
||||||
database = ["gotham_restful_derive/database", "gotham_middleware_diesel"]
|
database = ["gotham_restful_derive/database", "gotham_middleware_diesel"]
|
||||||
openapi = ["gotham_restful_derive/openapi", "indexmap", "openapiv3"]
|
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
|
StaticAuthHandler
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(feature = "fs")]
|
||||||
|
mod fs;
|
||||||
|
#[cfg(feature = "fs")]
|
||||||
|
pub use fs::File;
|
||||||
|
|
||||||
pub mod matcher;
|
pub mod matcher;
|
||||||
|
|
||||||
#[cfg(feature = "openapi")]
|
#[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
|
where
|
||||||
Err : Send + 'static,
|
Err : Send + 'static,
|
||||||
F : FnOnce() -> Result<Response, Err>
|
F : FnOnce() -> Result<Response, Err>
|
||||||
|
@ -142,13 +142,13 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "errorlog")]
|
#[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);
|
error!("The handler encountered an error: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "errorlog"))]
|
#[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>
|
impl<R : ResponseBody, E : Error> ResourceResult for Result<R, E>
|
||||||
where
|
where
|
||||||
|
@ -413,13 +413,11 @@ impl<T : ResourceResult<Err = SerdeJsonError>, E : Error> ResourceResult for Res
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
Ok(r) => r.into_response(),
|
Ok(r) => r.into_response(),
|
||||||
Err(e) => {
|
Err(e) => into_response_helper(|| {
|
||||||
into_response_helper(|| {
|
errorlog(&e);
|
||||||
errorlog(&e);
|
let err : ResourceError = e.into();
|
||||||
let err : ResourceError = e.into();
|
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
||||||
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
})
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,6 +512,7 @@ where
|
||||||
match self {
|
match self {
|
||||||
Ok(nc) => nc.into_response(),
|
Ok(nc) => nc.into_response(),
|
||||||
Err(e) => into_response_helper(|| {
|
Err(e) => into_response_helper(|| {
|
||||||
|
errorlog(&e);
|
||||||
let err : ResourceError = e.into();
|
let err : ResourceError = e.into();
|
||||||
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
||||||
})
|
})
|
||||||
|
@ -603,6 +602,7 @@ where
|
||||||
match self {
|
match self {
|
||||||
Ok(raw) => raw.into_response(),
|
Ok(raw) => raw.into_response(),
|
||||||
Err(e) => into_response_helper(|| {
|
Err(e) => into_response_helper(|| {
|
||||||
|
errorlog(&e);
|
||||||
let err : ResourceError = e.into();
|
let err : ResourceError = e.into();
|
||||||
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
Ok(Response::json(StatusCode::INTERNAL_SERVER_ERROR, serde_json::to_string(&err)?))
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Reference in a new issue