Skip to content
This repository has been archived by the owner on Oct 29, 2021. It is now read-only.

Feature/custom header #34

Merged
merged 33 commits into from
Feb 3, 2020
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e62e78d
feat: add header function for Responder
jk-gan Jan 2, 2020
0034e93
feat: add initial implementation to convert headers from CustomRespon…
jk-gan Jan 2, 2020
845b90e
refactor: refactor codes to reduce duplication
jk-gan Jan 2, 2020
587895d
refactor: ignore None headers case instead of panic it
jk-gan Jan 2, 2020
c736aaf
feat: add initial implementation for adding multiple headers at once
jk-gan Jan 2, 2020
9192de0
feat: add few test cases for responder
jk-gan Jan 5, 2020
533235d
test: add more test cases
jk-gan Jan 5, 2020
cc4293c
refactor: refactor responder implementation
jk-gan Jan 6, 2020
96d4684
refactor: make response::json return CustomResponder so we can chain …
jk-gan Jan 10, 2020
853a2c8
feat: add header function for Responder
jk-gan Jan 2, 2020
049220c
feat: add initial implementation to convert headers from CustomRespon…
jk-gan Jan 2, 2020
a174af8
refactor: refactor codes to reduce duplication
jk-gan Jan 2, 2020
68b921a
refactor: ignore None headers case instead of panic it
jk-gan Jan 2, 2020
51eb822
feat: add initial implementation for adding multiple headers at once
jk-gan Jan 2, 2020
8ffcb90
feat: add few test cases for responder
jk-gan Jan 5, 2020
36b7021
test: add more test cases
jk-gan Jan 5, 2020
fca4f9a
refactor: refactor responder implementation
jk-gan Jan 6, 2020
d0365f5
refactor: make response::json return CustomResponder so we can chain …
jk-gan Jan 10, 2020
a56eca7
feat: removed CustomResponder and added a Response struct to handle c…
jk-gan Feb 1, 2020
ae37763
chore: merge with origin
jk-gan Feb 1, 2020
22e16b7
feat: add response html method
jk-gan Feb 2, 2020
25660ba
refactor: refactor the syntax for some common status
jk-gan Feb 2, 2020
d859cb8
feat: now user can set custom header with string key
jk-gan Feb 2, 2020
e969cda
feat: add method to add headers string for response
jk-gan Feb 2, 2020
78c196a
fix: fix clyppy errors
jk-gan Feb 2, 2020
e747070
feat: add some alias methods
jk-gan Feb 2, 2020
fc7fd8a
fix: fix failed test cases
jk-gan Feb 2, 2020
2224358
fix: fix clippy error
jk-gan Feb 2, 2020
6610632
test: add test cases for response
jk-gan Feb 2, 2020
e335548
docs: add example for json response
jk-gan Feb 2, 2020
2d85244
fix: fix warnings from clippy nightly
jk-gan Feb 3, 2020
0ef559d
Merge branch 'develop' into feature/custom_header
jk-gan Feb 3, 2020
bc68323
fix: the main.rs now will import the correct header
jk-gan Feb 3, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ path = 'examples/hello.rs'
name = 'hello_handler'
path = 'examples/hello_handler.rs'

[[example]]
name = 'json'
path = 'examples/json.rs'

[package]
name = 'obsidian'
version = '0.1.0-alpha.1'
Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,41 @@ async fn main() {
}
```

## JSON Response
```rust
use obsidian::{
context::Context,
router::{Responder, Response},
App,
};
use serde::*;

async fn get_user(_ctx: Context) -> impl Responder {
#[derive(Serialize, Deserialize)]
struct User {
name: String,
};

let user = User {
name: String::from("Obsidian"),
};
Response::ok().json(user)
}

#[tokio::main]
async fn main() {
let mut app = App::new();
let addr = ([127, 0, 0, 1], 3000).into();

app.get("/user", get_user);

app.listen(&addr, || {
println!("server is listening to {}", &addr);
})
.await;
}
```

## Example Files

Example are located in `example/main.rs`.
Expand Down
31 changes: 31 additions & 0 deletions examples/json.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use obsidian::{
context::Context,
router::{Responder, Response},
App,
};
use serde::*;

async fn get_user(_ctx: Context) -> impl Responder {
#[derive(Serialize, Deserialize)]
struct User {
name: String,
};

let user = User {
name: String::from("Obsidian"),
};
Response::ok().json(user)
}

#[tokio::main]
async fn main() {
let mut app = App::new();
let addr = ([127, 0, 0, 1], 3000).into();

app.get("/user", get_user);

app.listen(&addr, || {
println!("server is listening to {}", &addr);
})
.await;
}
200 changes: 132 additions & 68 deletions examples/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::{fmt, fmt::Display};
use obsidian::{
context::Context,
middleware::Logger,
router::{response, Responder, Router},
router::{header, Responder, Response, Router},
App, StatusCode,
};

Expand All @@ -27,118 +27,180 @@ struct ParamTest {
test2: String,
}

#[derive(Serialize, Deserialize, Debug)]
struct Person {
name: String,
age: i8,
}

impl Display for JsonTest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{{title: {}, content: {}}}", self.title, self.content)
}
}

async fn responder_obsidian_error(mut ctx: Context) -> impl Responder {
let json: JsonTest = ctx.json().await?;
println!("{}", json);
Ok(response::json(json, StatusCode::OK))
}
// async fn responder_json(mut ctx: Context) -> impl Responder {
// let person: Person = ctx.json().await?;

// person.age += 1;

// Ok(response::json(person))
// }

// async fn responder_obsidian_error(mut ctx: Context) -> impl Responder {
// let json: JsonTest = ctx.json().await?;
// println!("{}", json);
// Ok(response::json(json, StatusCode::OK))
// }

// fn responder_with_header(_ctx: Context) -> impl Responder {
// let headers = vec![
// ("X-Custom-Header-4", "custom-value-4"),
// ("X-Custom-Header-5", "custom-value-5"),
// ];

// "here"
// .header("Content-Type", "application/json")
// .header("X-Custom-Header", "custom-value")
// .header("X-Custom-Header-2", "custom-value-2")
// .header("X-Custom-Header-3", "custom-value-3")
// .set_headers(headers)
// .status(StatusCode::CREATED)
// }

#[tokio::main]
async fn main() {
let mut app = App::new();
let addr = ([127, 0, 0, 1], 3000).into();

app.get("/", |_ctx| async {
"<!DOCTYPE html><html><head><link rel=\"shotcut icon\" href=\"favicon.ico\" type=\"image/x-icon\" sizes=\"32x32\" /></head> <h1>Hello Obsidian</h1></html>"
Response::ok().html("<!DOCTYPE html><html><head><link rel=\"shotcut icon\" href=\"favicon.ico\" type=\"image/x-icon\" sizes=\"32x32\" /></head> <h1>Hello Obsidian</h1></html>")
});

app.get("/json", |_ctx| {
async {
let point = Point { x: 1, y: 2 };
app.get("/json", |_ctx| async {
let point = Point { x: 1, y: 2 };

response::json(point, StatusCode::OK)
// res.header(header::CONTENT_TYPE, "application/json")
// .status(StatusCode::OK)
// .json(point)
}
Response::created()
.set_header(header::AUTHORIZATION, "token")
.set_header_str("X-Custom-Header", "Custom header value")
.json(point)
});

app.get("/empty-body", |_ctx| async { StatusCode::OK });
app.get("/json-with-headers", |_ctx| async {
let point = Point { x: 1, y: 2 };

app.get("/vec", |_ctx| async { vec![1, 2, 3] });
let custom_headers = vec![
("X-Custom-Header-1", "Custom header 1"),
("X-Custom-Header-2", "Custom header 2"),
("X-Custom-Header-3", "Custom header 3"),
];

app.get("/String", |_ctx| {
async { "<h1>This is a String</h1>".to_string() }
});
let standard_headers = vec![
(header::AUTHORIZATION, "token"),
(header::ACCEPT_CHARSET, "utf-8"),
];

app.get("/test/radix", |_ctx| {
async { "<h1>Test radix</h1>".to_string() }
Response::created()
.with_headers(standard_headers)
.with_headers_str(custom_headers)
.json(point)
});

app.get("/team/radix", |_ctx| {
async { "<h1>Team radix</h1>".to_string() }
app.get("/string-with-headers", |_ctx| async {
let custom_headers = vec![
("X-Custom-Header-1", "Custom header 1"),
("X-Custom-Header-2", "Custom header 2"),
("X-Custom-Header-3", "Custom header 3"),
];

let standard_headers = vec![
(header::AUTHORIZATION, "token"),
(header::ACCEPT_CHARSET, "utf-8"),
];

"Hello World"
.with_headers(standard_headers)
.with_headers_str(custom_headers)
});

app.get("/test/radix2", |_ctx| {
async { "<h1>Test radix2</h1>".to_string() }
app.get("/empty-body", |_ctx| async { StatusCode::OK });

app.get("/vec", |_ctx| async {
vec![1, 2, 3].with_status(StatusCode::CREATED)
});

app.get("/jsontest", |_ctx| {
async { response::file("./testjson.html").await }
app.get("/String", |_ctx| async {
"<h1>This is a String</h1>".to_string()
});

app.get("/jsan", |_ctx: Context| {
async { "<h1>jsan</h1>".to_string() }
app.get("/test/radix", |_ctx| async {
"<h1>Test radix</h1>".to_string()
});

app.post("/jsontestapi", |mut ctx: Context| {
async move {
let json: serde_json::Value = ctx.json().await?;
app.get("/team/radix", |_ctx| async { "Team radix".to_string() });

println!("{}", json);
app.get("/test/radix2", |_ctx| async {
"<h1>Test radix2</h1>".to_string()
});

app.get("/jsontest", |_ctx| async {
Response::ok().file("./testjson.html").await
});

Ok(response::json(json, StatusCode::OK))
}
app.get("/jsan", |_ctx: Context| async {
"<h1>jsan</h1>".to_string()
});

app.post("/jsonteststructapi", responder_obsidian_error);
// app.post("/jsontestapi", |mut ctx: Context| {
// async move {
// let json: serde_json::Value = ctx.json().await?;

// println!("{}", json);

app.get("/test/wildcard/*", |ctx: Context| {
async move {
format!(
"{}<br>{}",
"<h1>Test wildcard</h1>".to_string(),
ctx.uri().path()
)
}
// Ok(response::json(json, StatusCode::OK))
// }
// });

// app.post("/jsonteststructapi", responder_obsidian_error);

app.get("/test/wildcard/*", |ctx: Context| async move {
format!(
"{}<br>{}",
"<h1>Test wildcard</h1>".to_string(),
ctx.uri().path()
)
});

app.get("router/test", |ctx: Context| async move{
app.get("router/test", |ctx: Context| async move {
format!(
"{}<br>{}",
"<h1>router test get</h1>".to_string(),
ctx.uri().path()
)
});
app.post("router/test", |ctx: Context| async move{
app.post("router/test", |ctx: Context| async move {
format!(
"{}<br>{}",
"<h1>router test post</h1>".to_string(),
ctx.uri().path()
)
});
app.put("router/test", |ctx: Context| async move{
app.put("router/test", |ctx: Context| async move {
format!(
"{}<br>{}",
"<h1>router test put</h1>".to_string(),
ctx.uri().path()
)
});
app.delete("router/test", |ctx: Context| async move{
app.delete("router/test", |ctx: Context| async move {
format!(
"{}<br>{}",
"<h1>router test delete</h1>".to_string(),
ctx.uri().path()
)
});

app.get("route/diff_route", |ctx: Context| async move{
app.get("route/diff_route", |ctx: Context| async move {
format!(
"{}<br>{}",
"<h1>route diff get</h1>".to_string(),
Expand All @@ -148,35 +210,36 @@ async fn main() {

let mut form_router = Router::new();

form_router.get("/formtest", |_ctx| response::file("./test.html"));
form_router.get("/formtest", |_ctx| Response::ok().file("./test.html"));

form_router.post("/formtest", |mut ctx: Context| async move{
let param_test: ParamTest = ctx.form().await?;
// form_router.post("/formtest", |mut ctx: Context| async move{
// let param_test: ParamTest = ctx.form().await?;

dbg!(&param_test);
// dbg!(&param_test);

Ok(response::json(param_test, StatusCode::OK))
});
// Ok(response::json(param_test, StatusCode::OK))
// });

let mut param_router = Router::new();
let logger = Logger::new();
app.use_service(logger);

param_router.get("/paramtest/:id", |ctx: Context| async move {
let param_test: i32 = ctx.param("id")?;
// param_router.get("/paramtest/:id", |ctx: Context| async move {
// let param_test: i32 = ctx.param("id")?;

dbg!(&param_test);
// dbg!(&param_test);

Ok(response::json(param_test, StatusCode::OK))
});
param_router.get("/paramtest/:id/test", |ctx: Context| async move {
let mut param_test: i32 = ctx.param("id").unwrap();
param_test *= 10;
// Ok(response::json(param_test, StatusCode::OK))
// });
//
// param_router.get("/paramtest/:id/test", |ctx: Context| async move {
// let mut param_test: i32 = ctx.param("id").unwrap();
// param_test = param_test * 10;

dbg!(&param_test);
// dbg!(&param_test);

Ok(response::json(param_test, StatusCode::OK))
});
// Ok(response::json(param_test, StatusCode::OK))
// });

param_router.get("/test-next-wild/*", |_ctx| async {
"<h1>test next wild</h1>".to_string()
Expand All @@ -194,5 +257,6 @@ async fn main() {

app.listen(&addr, || {
println!("server is listening to {}", &addr);
}).await;
})
.await;
}
Loading