Skip to content

Commit

Permalink
Use Self::Error in returning error of {Front,Back}Fang & Update: …
Browse files Browse the repository at this point in the history
…examples, docs
  • Loading branch information
kanarus committed Feb 19, 2024
1 parent dde5837 commit f352d78
Show file tree
Hide file tree
Showing 15 changed files with 74 additions and 40 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,17 @@ use ohkami::prelude::*;
struct LogRequest;
impl FrontFang for LogRequest {
async fn bite(&self, req: &mut Request) -> Result<(), Response> {
type Error = std::convert::Infallible;
async fn bite(&self, req: &mut Request) -> Result<(), Self::Error> {
println!("{req:?}");
Ok(())
}
}
struct SetServer;
impl BackFang for SetServer {
async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Response> {
type Error = std::convert::Infallible;
async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Self::Error> {
res.headers.set()
.Server("ohkami");
Ok(())
Expand Down
3 changes: 2 additions & 1 deletion examples/form/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ async fn post_submit(form_data: FormData) -> Status {

struct Logger;
impl BackFang for Logger {
fn bite(&self, res: &mut Response, req: &Request) -> impl std::future::Future<Output = Result<(), Response>> + Send {
type Error = std::convert::Infallible;
fn bite(&self, res: &mut Response, req: &Request) -> impl std::future::Future<Output = Result<(), Self::Error>> + Send {
println!("[request ] {:?}", req);
println!("[response] {:?}", res);

Expand Down
6 changes: 4 additions & 2 deletions examples/hello/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ mod fangs {

pub struct SetServer;
impl BackFang for SetServer {
async fn bite(&self, res: &mut Response, _: &Request) -> Result<(), Response> {
type Error = std::convert::Infallible;
async fn bite(&self, res: &mut Response, _: &Request) -> Result<(), Self::Error> {
res.headers.set()
.Server("ohkami");

Expand All @@ -82,7 +83,8 @@ mod fangs {

pub struct LogRequest;
impl FrontFang for LogRequest {
async fn bite(&self, req: &mut Request) -> Result<(), Response> {
type Error = std::convert::Infallible;
async fn bite(&self, req: &mut Request) -> Result<(), Self::Error> {
let __method__ = req.method();
let __path__ = req.path();

Expand Down
16 changes: 10 additions & 6 deletions examples/realworld/src/fangs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ impl Default for Auth {
}
}
impl FrontFang for Auth {
type Error = Response;
async fn bite(&self, req: &mut Request) -> Result<(), Response> {
if self.condition.is_some_and(|cond| !cond(req)) {
return Ok(());
Expand Down Expand Up @@ -44,13 +45,13 @@ impl Default for OptionalAuth {
}
}
impl FrontFang for OptionalAuth {
async fn bite(&self, req: &mut Request) -> Result<(), Response> {
type Error = RealWorldError;
async fn bite(&self, req: &mut Request) -> Result<(), Self::Error> {
if self.condition.is_some_and(|cond| !cond(req)) {
return Ok(());
}

let secret = config::JWT_SECRET_KEY()
.map_err(RealWorldError::into_response)?;
let secret = config::JWT_SECRET_KEY()?;
let payload: Option<config::JWTPayload> = JWT::default(secret).verified(req).ok();
req.memorize(payload);
Ok(())
Expand All @@ -59,7 +60,8 @@ impl FrontFang for OptionalAuth {

pub struct LogRequest;
impl FrontFang for LogRequest {
fn bite(&self, req: &mut Request) -> impl std::future::Future<Output = Result<(), Response>> + Send {
type Error = std::convert::Infallible;
fn bite(&self, req: &mut Request) -> impl std::future::Future<Output = Result<(), Self::Error>> + Send {
let method = req.method();
let path = req.path();

Expand All @@ -71,15 +73,17 @@ impl FrontFang for LogRequest {

pub struct LogResponse;
impl BackFang for LogResponse {
fn bite(&self, res: &mut Response, _: &Request) -> impl std::future::Future<Output = Result<(), Response>> + Send {
type Error = std::convert::Infallible;
fn bite(&self, res: &mut Response, _: &Request) -> impl std::future::Future<Output = Result<(), Self::Error>> + Send {
tracing::info!("{res:?}");
async {Ok(())}
}
}

pub struct ConnectionPool(PgPool);
impl FrontFang for ConnectionPool {
fn bite(&self, req: &mut Request) -> impl std::future::Future<Output = Result<(), Response>> + Send {
type Error = std::convert::Infallible;
fn bite(&self, req: &mut Request) -> impl std::future::Future<Output = Result<(), Self::Error>> + Send {
req.memorize(self.0.clone());
async {Ok(())}
}
Expand Down
2 changes: 2 additions & 0 deletions ohkami/src/fang/builtin/cors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ impl CORS {

/* Based on https://github.com/honojs/hono/blob/main/src/middleware/cors/index.ts; MIT */
impl BackFang for CORS {
type Error = Response;

async fn bite(&self, res: &mut Response, req: &Request) -> Result<(), Response> {
let mut h = res.headers.set();

Expand Down
4 changes: 3 additions & 1 deletion ohkami/src/fang/builtin/jwt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ use crate::{Request, Response, Status};
///
/// struct MyAuthFang;
/// impl FrontFang for MyAuthFang {
/// async fn bite(&self, req: &mut Request) -> Result<(), Response> {
/// type Error = Response;
/// async fn bite(&self, req: &mut Request) -> Result<(), Self::Error> {
/// let payload = my_jwt()
/// .verified::<JWTPayload>(req)?;
/// req.memorize(payload);
Expand Down Expand Up @@ -468,6 +469,7 @@ impl JWT {

struct MyJWTFang(JWT);
impl FrontFang for MyJWTFang {
type Error = Response;
async fn bite(&self, req: &mut Request) -> Result<(), Response> {
let jwt_payload = self.0.verified::<MyJWTPayload>(req)?;
req.memorize(jwt_payload);
Expand Down
34 changes: 23 additions & 11 deletions ohkami/src/fang/fangs.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::{future::Future, pin::Pin};
use crate::{Response, Request, Method::{self, *}, fang::Fang};
use crate::{Response, Request, IntoResponse, Method::{self, *}, fang::Fang};


/// Represents "can be used as a front fang", e.g. executed before `req` is passed to a handler.\
Expand All @@ -13,7 +13,8 @@ use crate::{Response, Request, Method::{self, *}, fang::Fang};
///
/// struct LogRequest;
/// impl FrontFang for LogRequest {
/// async fn bite(&self, req: &mut Request) -> Result<(), Response> {
/// type Error = std::convert::Infallible;
/// async fn bite(&self, req: &mut Request) -> Result<(), Self::Error> {
/// println!("{req:?}");
/// Ok(())
/// }
Expand All @@ -22,9 +23,12 @@ use crate::{Response, Request, Method::{self, *}, fang::Fang};
pub trait FrontFang {
const METHODS: &'static [Method] = &[GET, PUT, POST, PATCH, DELETE, HEAD, OPTIONS];

/// If `bite` never fails, `std::convert::Infallible` is recommended.
type Error: IntoResponse;

#[must_use]
#[allow(clippy::type_complexity)]
fn bite(&self, req: &mut Request) -> impl ::std::future::Future<Output = Result<(), Response>> + Send;
fn bite(&self, req: &mut Request) -> impl ::std::future::Future<Output = Result<(), Self::Error>> + Send;
}

pub(crate) trait FrontFangCaller: Send + Sync {
Expand All @@ -33,9 +37,11 @@ pub(crate) trait FrontFangCaller: Send + Sync {
}
impl<FF: FrontFang + Send + Sync> FrontFangCaller for FF {
#[inline(always)] fn call<'c>(&'c self, req: &'c mut Request) -> Pin<Box<dyn Future<Output = Result<(), Response>> + Send + 'c>>
where Self: Sync + 'c
{
Box::pin(self.bite(req))
where Self: Sync + 'c {
Box::pin(async {
self.bite(req).await
.map_err(IntoResponse::into_response)
})
}
}

Expand All @@ -51,7 +57,8 @@ impl<FF: FrontFang + Send + Sync> FrontFangCaller for FF {
///
/// struct LogResponse;
/// impl BackFang for LogResponse {
/// async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Response> {
/// type Error = std::convert::Infallible;
/// async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Self::Error> {
/// println!("{res:?}");
/// Ok(())
/// }
Expand All @@ -60,9 +67,12 @@ impl<FF: FrontFang + Send + Sync> FrontFangCaller for FF {
pub trait BackFang {
const METHODS: &'static [Method] = &[GET, PUT, POST, PATCH, DELETE, HEAD, OPTIONS];

/// If `bite` never fails, `std::convert::Infallible` is recommended.
type Error: IntoResponse;

#[must_use]
#[allow(clippy::type_complexity)]
fn bite(&self, res: &mut Response, _req: &Request) -> impl ::std::future::Future<Output = Result<(), Response>> + Send;
fn bite(&self, res: &mut Response, _req: &Request) -> impl ::std::future::Future<Output = Result<(), Self::Error>> + Send;
}

pub(crate) trait BackFangCaller: Send + Sync {
Expand All @@ -71,9 +81,11 @@ pub(crate) trait BackFangCaller: Send + Sync {
}
impl<BF: BackFang + Send + Sync> BackFangCaller for BF {
#[inline(always)] fn call<'c>(&'c self, res: &'c mut Response, _req: &'c Request) -> Pin<Box<dyn Future<Output = Result<(), Response>> + Send + 'c>>
where Self: Sync + 'c
{
Box::pin(self.bite(res, _req))
where Self: Sync + 'c {
Box::pin(async {
self.bite(res, _req).await
.map_err(IntoResponse::into_response)
})
}
}

Expand Down
3 changes: 2 additions & 1 deletion ohkami/src/fang/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ use std::any::TypeId;
///
/// struct SetServer;
/// impl BackFang for SetServer {
/// async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Response> {
/// type Error = std::convert::Infallible;
/// async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Self::Error> {
/// res.headers.set()
/// .Server("ohkami");
/// Ok(())
Expand Down
3 changes: 2 additions & 1 deletion ohkami/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ mod x_websocket;
///
/// struct SetServer;
/// impl BackFang for SetServer {
/// async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Response> {
/// type Error = std::convert::Infallible;
/// async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Self::Error> {
/// res.headers.set()
/// .Server(append("ohkami"));
/// Ok(())
Expand Down
6 changes: 4 additions & 2 deletions ohkami/src/ohkami/howl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,17 @@ impl Ohkami {
///
/// struct LogRequest;
/// impl FrontFang for LogRequest {
/// async fn bite(&self, req: &mut Request) -> Result<(), Response> {
/// type Error = std::convert::Infallible;
/// async fn bite(&self, req: &mut Request) -> Result<(), Self::Error> {
/// println!("{req:?}");
/// Ok(())
/// }
/// }
///
/// struct CustomNotFound;
/// impl BackFang for CustomNotFound {
/// async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Response> {
/// type Error = std::convert::Infallible;
/// async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Self::Error> {
/// if res.status == Status::NotFound {
/// res.set_html(r#"
/// <!DOCTYPE html>
Expand Down
6 changes: 4 additions & 2 deletions ohkami/src/ohkami/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use crate::Method;
/// struct Auth;
/// impl FrontFang for Auth {
/// /* 〜 */
/// # async fn bite(&self, req: &mut Request) -> Result<(), Response> {
/// # type Error = Response;
/// # async fn bite(&self, req: &mut Request) -> Result<(), Self::Error> {
/// # // Do something...
/// #
/// # Ok(())
Expand Down Expand Up @@ -185,7 +186,8 @@ impl Ohkami {
///
/// struct Auth;
/// impl FrontFang for Auth {
/// async fn bite(&self, req: &mut Request) -> Result<(), Response> {
/// type Error = Response;
/// async fn bite(&self, req: &mut Request) -> Result<(), Self::Error> {
/// Ok(())
/// }
/// }
Expand Down
14 changes: 8 additions & 6 deletions ohkami/src/ohkami/router/_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,8 @@ fn my_ohkami() -> Ohkami {

struct Increment;
impl FrontFang for Increment {
fn bite(&self, _: &mut Request) -> impl std::future::Future<Output = Result<(), Response>> + Send {
*N().lock().unwrap() += 1;

type Error = std::convert::Infallible;
fn bite(&self, _: &mut Request) -> impl std::future::Future<Output = Result<(), Self::Error>> + Send { *N().lock().unwrap() += 1;
async {Ok(())}
}
}
Expand Down Expand Up @@ -261,23 +260,26 @@ fn my_ohkami() -> Ohkami {

struct APIIncrement;
impl FrontFang for APIIncrement {
fn bite(&self, _: &mut Request) -> impl std::future::Future<Output = Result<(), Response>> + Send {
type Error = std::convert::Infallible;
fn bite(&self, _: &mut Request) -> impl std::future::Future<Output = Result<(), Self::Error>> + Send {
*N().lock().unwrap() += 1;
async {Ok(())}
}
}

struct GlobalIncrement;
impl FrontFang for GlobalIncrement {
fn bite(&self, _: &mut Request) -> impl std::future::Future<Output = Result<(), Response>> + Send {
type Error = std::convert::Infallible;
fn bite(&self, _: &mut Request) -> impl std::future::Future<Output = Result<(), Self::Error>> + Send {
*N().lock().unwrap() += 2;
async {Ok(())}
}
}

struct NotFoundIncrement;
impl BackFang for NotFoundIncrement {
fn bite(&self, res: &mut Response, _req: &Request) -> impl std::future::Future<Output = Result<(), Response>> + Send {
type Error = std::convert::Infallible;
fn bite(&self, res: &mut Response, _req: &Request) -> impl std::future::Future<Output = Result<(), Self::Error>> + Send {
if res.status == Status::NotFound {
*N().lock().unwrap() += 3;
}
Expand Down
5 changes: 2 additions & 3 deletions ohkami/src/request/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ pub(crate) const PAYLOAD_LIMIT: usize = 1 << 32;
///
/// struct LogRequest;
/// impl FrontFang for LogRequest {
/// async fn bite(&self, req: &mut Request) -> Result<(), Response> {
/// type Error = std::convert::Infallible;
/// async fn bite(&self, req: &mut Request) -> Result<(), Self::Error> {
/// let method = req.method();
/// let path = req.path();
/// println!("{method} {path}");
Expand Down Expand Up @@ -105,8 +106,6 @@ pub struct Request {pub(crate) _metadata: [u8; METADATA_SIZE],
queries: QueryParams,
payload: Option<CowSlice>,
store: Store,

#[cfg(feature="websocket")] pub(crate) upgrade_id: Option<UpgradeID>,
}

impl Request {
Expand Down
3 changes: 2 additions & 1 deletion ohkami/src/request/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ impl Hasher for TypeIDHasger {
///
/// pub struct MemorizeNow;
/// impl FrontFang for MemorizeNow {
/// async fn bite(&self, req: &mut Request) -> Result<(), Response> {
/// type Error = std::convert::Infallible;
/// async fn bite(&self, req: &mut Request) -> Result<(), Self::Error> {
/// req.memorize(serde_json::json!({
/// "now": std::time::SystemTime::now()
/// }));
Expand Down
3 changes: 2 additions & 1 deletion ohkami/src/response/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ use crate::__rt__::AsyncWriter;
///
/// struct LogResponse;
/// impl BackFang for LogResponse {
/// async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Response> {
/// type Error = std::convert::Infallible;
/// async fn bite(&self, res: &mut Response, _req: &Request) -> Result<(), Self::Error> {
/// println!("{}", res.status);
/// Ok(())
/// }
Expand Down

0 comments on commit f352d78

Please sign in to comment.