Skip to content

Commit 1d19ece

Browse files
authored
Renew fang util (#113)
* boxize large arrays & fix wrong size tracking in response headers & remove `custom-header` feature and default to support cutom headers & add test case for custom header handling in response headers * next: some performance tuning * Update response headers: specialize when insert `&'static str` value * Update response headers: specialize when insert `&'static str` value * Add: benches/src/bin/hello * remove `const LOOP_LIMIT: u8 = 16;` in `Session::manage` * Update: Taskfile::bench* * remove `{Back,Fore,Front}Fang` & add `FangAction`; next: update docs * Update docs & Fix some to pass tasks
1 parent 068d10c commit 1d19ece

File tree

17 files changed

+318
-349
lines changed

17 files changed

+318
-349
lines changed

Diff for: README.md

+47-18
Original file line numberDiff line numberDiff line change
@@ -146,34 +146,51 @@ ohkami's request handling system is called "**fang**s", and middlewares are impl
146146
```rust,no_run
147147
use ohkami::prelude::*;
148148
149-
struct GreetFang;
150-
impl<I: FangProc> Fang<I> for GreetFang {
151-
type Proc = GreetFangProc<I>;
149+
150+
/* Full impl */
151+
152+
use ohkami::{Fang, FangProc};
153+
154+
struct GreetingFang;
155+
impl<I: FangProc> Fang<I> for GreetingFang {
156+
type Proc = GreetingFangProc<I>;
152157
fn chain(&self, inner: I) -> Self::Proc {
153-
GreetFangProc { inner }
158+
GreetingFangProc { inner }
154159
}
155160
}
156-
157-
struct GreetFangProc<I: FangProc> {
161+
struct GreetingFangProc<I: FangProc> {
158162
inner: I
159163
}
160-
impl<I: FangProc> FangProc for GreetFangProc<I> {
164+
impl<I: FangProc> FangProc for GreetingFangProc<I> {
161165
async fn bite<'b>(&'b self, req: &'b mut Request) -> Response {
162-
println!("Welcome, request!\n{req:?}");
166+
println!("Welcome, request!: {req:?}");
163167
let res = self.inner.bite(req).await;
164-
println!("My response: \n{res:?}");
168+
println!("Go, response!: {res:?}");
165169
res
166170
}
167171
}
168172
173+
174+
/* Easy impl with an utility */
175+
176+
#[derive(Clone)]
177+
struct GreetingFang2;
178+
impl FangAction for GreetingFang2 {
179+
async fn fore<'a>(&'a self, req: &'a mut Request) -> Result<(), Response> {
180+
println!("Welcomm request!: {req:?}");
181+
Ok(())
182+
}
183+
async fn back<'a>(&'a self, res: &'a mut Response) {
184+
println!("Go, response!: {res:?}");
185+
}
186+
}
187+
188+
169189
#[tokio::main]
170190
async fn main() {
171191
Ohkami::with((
172-
/* Your `Fang` value */
173-
GreetFang,
174-
175-
/* Inline Fang with utils */
176-
ohkami::utils::ForeFang(|req| println!("{}", req.path())),
192+
GreetingFang,
193+
GreetingFang2,
177194
), (
178195
"/".GET(|| async {"Hello, fangs!"})
179196
)).howl("localhost:3000").await
@@ -194,9 +211,17 @@ struct User {
194211
name: String
195212
}
196213
214+
async fn list_users() -> Vec<User> {
215+
vec![
216+
User { name: String::from("actix") },
217+
User { name: String::from("axum") },
218+
User { name: String::from("ohkami") },
219+
]
220+
}
221+
197222
async fn create_user() -> Created<User> {
198223
Created(User {
199-
name: "ohkami web framework".to_string()
224+
name: String::from("ohkami web framework")
200225
})
201226
}
202227
@@ -209,12 +234,16 @@ async fn main() {
209234
// ...
210235
211236
let users_ohkami = Ohkami::new((
212-
"/".POST(create_user),
237+
"/"
238+
.GET(list_users)
239+
.POST(create_user),
213240
));
214241
215242
Ohkami::new((
216-
"/healthz" .GET(health_check),
217-
"/api/users".By(users_ohkami), // <-- nest by `By`
243+
"/healthz"
244+
.GET(health_check),
245+
"/api/users"
246+
.By(users_ohkami), // nest by `By`
218247
)).howl("localhost:5000").await
219248
}
220249
```

Diff for: benches/src/bin/hello.rs

+8-18
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,17 @@
11
use ohkami::prelude::*;
22
use ohkami::{typed::Payload, builtin::payload::JSON};
33

4+
#[derive(Clone)]
45
struct Logger;
5-
const _: () = {
6-
impl<I: FangProc> Fang<I> for Logger {
7-
type Proc = LoggerProc<I>;
8-
fn chain(&self, inner: I) -> Self::Proc {
9-
LoggerProc { inner }
10-
}
6+
impl FangAction for Logger {
7+
async fn fore<'a>(&'a self, req: &'a mut Request) -> Result<(), Response> {
8+
tracing::info!("\n{req:?}");
9+
Ok(())
1110
}
12-
13-
struct LoggerProc<I: FangProc> {
14-
inner: I
15-
}
16-
impl<I: FangProc> FangProc for LoggerProc<I> {
17-
async fn bite<'b>(&'b self, req: &'b mut Request) -> Response {
18-
tracing::info!("\n{req:?}");
19-
let res = self.inner.bite(req).await;
20-
tracing::info!("\n{res:?}");
21-
res
22-
}
11+
async fn back<'a>(&'a self, res: &'a mut Response) {
12+
tracing::info!("\n{res:?}");
2313
}
24-
};
14+
}
2515

2616
#[Payload(JSON/S)]
2717
struct Message {

Diff for: examples/form/src/main.rs

+9-20
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,17 @@ async fn post_submit(form_data: FormData<'_>) -> NoContent {
3737
NoContent
3838
}
3939

40-
41-
struct Logger; const _: () = {
42-
impl<I: FangProc> Fang<I> for Logger {
43-
type Proc = LoggerProc<I>;
44-
fn chain(&self, inner: I) -> Self::Proc {
45-
LoggerProc { inner }
46-
}
40+
#[derive(Clone)]
41+
struct Logger;
42+
impl FangAction for Logger {
43+
async fn fore<'a>(&'a self, req: &'a mut Request) -> Result<(), Response> {
44+
println!("\n[req]\n{req:#?}");
45+
Ok(())
4746
}
48-
49-
struct LoggerProc<I: FangProc> { inner: I }
50-
impl<I: FangProc> FangProc for LoggerProc<I> {
51-
async fn bite<'b>(&'b self, req: &'b mut Request) -> Response {
52-
println!("\n[req]\n{req:#?}");
53-
54-
let res = self.inner.bite(req).await;
55-
56-
println!("\n[res]\n{res:#?}");
57-
58-
res
59-
}
47+
async fn back<'a>(&'a self, res: &'a mut Response) {
48+
println!("\n[res]\n{res:#?}");
6049
}
61-
};
50+
}
6251

6352
#[tokio::main]
6453
async fn main() {

Diff for: examples/hello/src/main.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,12 @@ mod hello_handler {
6464

6565

6666
mod fangs {
67-
pub mod back {
68-
use ohkami::Response;
67+
use ohkami::prelude::*;
6968

70-
pub fn set_server(res: &mut Response) {
69+
#[derive(Clone)]
70+
pub struct SetServer;
71+
impl FangAction for SetServer {
72+
fn back<'a>(&'a self, res: &'a mut Response) -> impl std::future::Future<Output = ()> + Send {
7173
res.headers.set()
7274
.Server("ohkami");
7375

@@ -76,13 +78,15 @@ mod fangs {
7678
[current headers]\n\
7779
{:?}\n\
7880
", res.headers);
81+
82+
async {}
7983
}
8084
}
8185

82-
pub mod front {
83-
use ohkami::Request;
84-
85-
pub fn log_request(req: &mut Request) {
86+
#[derive(Clone)]
87+
pub struct LogRequest;
88+
impl FangAction for LogRequest {
89+
fn fore<'a>(&'a self, req: &'a mut Request) -> impl std::future::Future<Output = Result<(), Response>> + Send {
8690
let __method__ = req.method();
8791
let __path__ = req.path();
8892

@@ -91,6 +95,8 @@ mod fangs {
9195
[ method ] {__method__}\n\
9296
[ path ] {__path__}\n\
9397
");
98+
99+
async {Ok(())}
94100
}
95101
}
96102
}
@@ -99,14 +105,13 @@ mod fangs {
99105
#[tokio::main]
100106
async fn main() {
101107
use ohkami::prelude::*;
102-
use ohkami::utils::{BackFang, ForeFang};
103108

104109
tracing_subscriber::fmt()
105110
.with_max_level(tracing::Level::INFO)
106111
.init();
107112

108113
let hello_ohkami = Ohkami::with((
109-
BackFang(fangs::back::set_server),
114+
fangs::SetServer,
110115
), (
111116
"/query".
112117
GET(hello_handler::hello_by_query),
@@ -117,7 +122,7 @@ async fn main() {
117122
tracing::info!("Started listening on http://localhost:3000");
118123

119124
Ohkami::with((
120-
ForeFang(fangs::front::log_request),
125+
fangs::LogRequest,
121126
), (
122127
"/hc" .GET(health_handler::health_check),
123128
"/api".By(hello_ohkami),

Diff for: examples/realworld/docker-compose.yml

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3'
2-
31
services:
42
postgres:
53
image: postgres:15-alpine

Diff for: examples/realworld/src/fangs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ const _: () = {
169169
inner: I,
170170
}
171171
impl<I: FangProc> FangProc for ConnectionPoolProc<I> {
172-
fn bite<'b>(&'b self, req: &'b mut Request) -> impl std::future::Future<Output = Response> + Send + 'b {
172+
fn bite<'b>(&'b self, req: &'b mut Request) -> impl std::future::Future<Output = Response> + Send {
173173
req.memorize(self.pool.clone());
174174
self.inner.bite(req)
175175
}

Diff for: ohkami/src/builtin/fang/timeout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const _: () = {
7373
time: Duration,
7474
}
7575
impl<Inner: FangProc> FangProc for TimeoutProc<Inner> {
76-
fn bite<'b>(&'b self, req: &'b mut Request) -> impl Future<Output = Response> + Send + 'b {
76+
fn bite<'b>(&'b self, req: &'b mut Request) -> impl Future<Output = Response> + Send {
7777
set_timeout(self.time, self.inner.bite(req))
7878
}
7979
}

Diff for: ohkami/src/fangs/middleware/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pub mod utils;
1+
pub mod util;
22

33
use super::{Fang, BoxedFPC};
44

0 commit comments

Comments
 (0)