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

Feature/better error #64

Open
wants to merge 33 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
001149b
feat: move handler into separate folder
jk-gan May 6, 2020
c0305f2
docs: add docs for Middleware trait
jk-gan May 7, 2020
25ee344
docs: add example to import Middleware trait from obsidian
jk-gan May 7, 2020
e933273
docs: fix some docs error in Middleware trait
jk-gan May 7, 2020
7c2fa11
chore: rename middleware -> middlewares inside EndpointExecutor to av…
jk-gan May 7, 2020
94583bb
feat: modify app.listen to accept port number only to simplify the code
jk-gan May 9, 2020
5f3b689
docs: removed unused codes in README
jk-gan May 10, 2020
8499fac
docs: remove extra lines
jk-gan May 17, 2020
57ed5c2
feat: add source for ObsidianError
jk-gan May 20, 2020
8f2cae3
docs: modify readme
jk-gan May 21, 2020
d122a67
docs: modify the layout of readme
jk-gan May 21, 2020
fd9f1eb
docs: add bash syntax highlighting for bash command
jk-gan May 21, 2020
e3d74e3
docs: fix some wordings
jk-gan May 21, 2020
76f38fe
docs: fix typos
jk-gan May 21, 2020
7dbd7f4
docs: remove extra spacing
jk-gan May 21, 2020
e7113f8
docs: Add app lifecycle image
jk-gan May 23, 2020
8bd2d2f
docs: fix the lifecycle link
jk-gan May 23, 2020
dbda0c9
docs: reduce lifecycle image size
jk-gan May 23, 2020
62cdc6c
feat: initial implementation of IntoErrorResponse
jk-gan May 23, 2020
bd7c656
feat: simplify IntoErrorResponse trait
jk-gan May 24, 2020
380768b
fix: fix the potential crash in the logger middleware
jk-gan May 24, 2020
81814dc
fix: remove unused codes
jk-gan May 25, 2020
e3aaa44
feat: make handler return impl Responder
jk-gan May 31, 2020
b7a1e1f
feat: build method is no longer own the context
jk-gan May 31, 2020
a94f7b5
fix: remove warnings
jk-gan May 31, 2020
b063d10
chore: fix the examples
jk-gan May 31, 2020
78f1d1a
docs: add contributors section
jk-gan Jun 7, 2020
cfd961a
feat: add Responder for Result<T, E>
jk-gan Jun 7, 2020
d05134b
docs: fix the app state example
jk-gan Jun 7, 2020
5c8fbc2
docs: fix main example to match the latest framework version
jk-gan Jun 7, 2020
07d8166
feat: add Responder for ContextResult
jk-gan Jun 8, 2020
2395b08
fix: fix some typo
jk-gan Jun 21, 2020
634155e
fix: fix some error after rebase to develop
jk-gan Jul 4, 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
57 changes: 29 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
<img alt="Obsidian serve" src="./screenshot/serve.png" >
</div>

## Get Started
```toml
[dependencies]
# add these 2 dependencies in Cargo.toml file
obsidian = "0.2.2"
tokio = "0.2.21"
```

## Hello World

```rust
Expand All @@ -30,44 +38,32 @@ use obsidian::{context::Context, App};
#[tokio::main]
async fn main() {
let mut app: App = App::new();
let addr = ([127, 0, 0, 1], 3000).into();

app.get("/", |ctx: Context| async { ctx.build("Hello World").ok() });

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

## Hello World (with handler function)

```rust
use obsidian::{context::Context, App, ContextResult};
use obsidian::{context::Context, handler::ContextResult, App};

async fn hello_world(ctx: Context) -> ContextResult {
ctx.build("Hello World").ok()
}


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

app.get("/", hello_world);

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

## JSON Response

```rust
use obsidian::{context::Context, App, ContextResult};
use obsidian::{context::Context, handler::ContextResult, App};
use serde::*;

async fn get_user(ctx: Context) -> ContextResult {
Expand All @@ -85,28 +81,33 @@ async fn get_user(ctx: Context) -> ContextResult {
#[tokio::main]
async fn main() {
let mut app: 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;
app.listen(3000).await;
}

```

## Example Files
## More Examples

Example are located in `example/main.rs`.
Examples are located in `example` folder. You can run these examples by using:
```bash
cargo run --example [name]

## Run Example
// show a list of available examples
cargo run --example

```
// run the example
cargo run --example example
```

## App Lifecycle
![app lifecycle](./screenshot/lifecycle.png)

## Contributors
<a href="https://github.com/obsidian-rs/obsidian/graphs/contributors">
<img src="https://contributors-img.web.app/image?repo=obsidian-rs/obsidian" />
</a>

## Current State

NOT READY FOR PRODUCTION YET!
Under active development and **NOT READY FOR PRODUCTION YET!**
21 changes: 10 additions & 11 deletions examples/app_state.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use obsidian::{context::Context, App, ObsidianError};
use obsidian::{context::Context, App};

#[derive(Clone)]
pub struct AppState {
Expand All @@ -8,21 +8,20 @@ pub struct AppState {
#[tokio::main]
async fn main() {
let mut app: App<AppState> = App::new();
let addr = ([127, 0, 0, 1], 3000).into();

app.set_app_state(AppState {
db_connection_string: "localhost:1433".to_string()
db_connection_string: "localhost:1433".to_string(),
});

app.get("/", |ctx: Context| async {
let app_state = ctx.get::<AppState>().ok_or(ObsidianError::NoneError)?;
let res = Some(format!("connection string: {}", &app_state.db_connection_string));
app.get("/", |ctx: Context| async move {
let app_state = ctx.get::<AppState>().unwrap();
let res = Some(format!(
"connection string: {}",
&app_state.db_connection_string
));

ctx.build(res).ok()
res
});

app.listen(&addr, || {
println!("server is listening to {}", &addr);
})
.await;
app.listen(3000).await;
}
8 changes: 2 additions & 6 deletions examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@ use obsidian::{context::Context, App};
#[tokio::main]
async fn main() {
let mut app: App = App::new();
let addr = ([127, 0, 0, 1], 3000).into();

app.get("/", |ctx: Context| async { ctx.build("Hello World").ok() });
app.get("/", |_ctx: Context| async { "Hello, Obsidian!" });

app.listen(&addr, || {
println!("server is listening to {}", &addr);
})
.await;
app.listen(3000).await;
}
9 changes: 3 additions & 6 deletions examples/hello_handler.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
use obsidian::{context::Context, App, ContextResult};
use obsidian::{context::Context, handler::ContextResult, App};

// this is handler function
async fn hello_world(ctx: Context) -> ContextResult {
ctx.build("Hello World").ok()
}

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

app.get("/", hello_world);

app.listen(&addr, || {
println!("server is listening to {}", &addr);
})
.await;
app.listen(3000).await;
}
25 changes: 13 additions & 12 deletions examples/json.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
use obsidian::{context::Context, App, ContextResult};
use obsidian::{context::Context, handler::ContextResult, router::Response, App};
use serde::*;

async fn get_user(ctx: Context) -> ContextResult {
#[derive(Serialize, Deserialize)]
async fn get_user(mut ctx: Context) -> ContextResult {
#[derive(Serialize, Deserialize, Debug)]
struct User {
name: String,
};

let user = User {
name: String::from("Obsidian"),
#[derive(Serialize, Deserialize, Debug)]
struct UserParam {
name: String,
age: i8,
};
ctx.build_json(user).ok()

let user: UserParam = ctx.json().await?;

Ok(Response::ok().json(user))
}

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

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

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

// Testing example
Expand Down Expand Up @@ -66,20 +66,18 @@ impl Display for JsonTest {
// .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)
// .set_headers(headers) .status(StatusCode::CREATED)
// }

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

app.get("/", |ctx: Context| async {
app.get("/", |ctx: Context| async move {
ctx.build(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>")).ok()
});

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

ctx.build_json(point)
Expand All @@ -89,7 +87,7 @@ ctx.build(Response::ok().html("<!DOCTYPE html><html><head><link rel=\"shotcut ic
.ok()
});

app.get("/user", |mut ctx: Context| async {
app.get("/user", |mut ctx: Context| async move {
#[derive(Serialize, Deserialize, Debug)]
struct QueryString {
id: String,
Expand All @@ -112,11 +110,11 @@ ctx.build(Response::ok().html("<!DOCTYPE html><html><head><link rel=\"shotcut ic
ctx.build("").ok()
});

app.patch("/patch-here", |ctx: Context| async {
app.patch("/patch-here", |ctx: Context| async move {
ctx.build("Here is patch request").ok()
});

app.get("/json-with-headers", |ctx: Context| async {
app.get("/json-with-headers", |ctx: Context| async move {
let point = Point { x: 1, y: 2 };

let custom_headers = vec![
Expand All @@ -139,7 +137,7 @@ ctx.build(Response::ok().html("<!DOCTYPE html><html><head><link rel=\"shotcut ic
.ok()
});

app.get("/string-with-headers", |ctx: Context| async {
app.get("/string-with-headers", |ctx: Context| async move {
let custom_headers = vec![
("X-Custom-Header-1", "Custom header 1"),
("X-Custom-Header-2", "Custom header 2"),
Expand All @@ -157,37 +155,37 @@ ctx.build(Response::ok().html("<!DOCTYPE html><html><head><link rel=\"shotcut ic
.ok()
});

app.get("/empty-body", |ctx: Context| async {
app.get("/empty-body", |ctx: Context| async move {
ctx.build(StatusCode::OK).ok()
});

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

app.get("/String", |ctx: Context| async {
app.get("/String", |ctx: Context| async move {
ctx.build("<h1>This is a String</h1>".to_string()).ok()
});

app.get("/test/radix", |ctx: Context| async {
app.get("/test/radix", |ctx: Context| async move {
ctx.build("<h1>Test radix</h1>".to_string()).ok()
});

app.get("/team/radix", |ctx: Context| async {
app.get("/team/radix", |ctx: Context| async move {
ctx.build("Team radix".to_string()).ok()
});

app.get("/test/radix2", |ctx: Context| async {
app.get("/test/radix2", |ctx: Context| async move {
ctx.build("<h1>Test radix2</h1>".to_string()).ok()
});

app.get("/jsontest", |ctx: Context| async {
app.get("/jsontest", |ctx: Context| async move {
ctx.build_file("./testjson.html").await.ok()
});

app.get("/jsan", |ctx: Context| async {
app.get("/jsan", |ctx: Context| async move {
ctx.build("<h1>jsan</h1>".to_string()).ok()
});

Expand All @@ -202,10 +200,7 @@ ctx.build(Response::ok().html("<!DOCTYPE html><html><head><link rel=\"shotcut ic
});

app.get("router/test", |ctx: Context| async move {
let result = ctx
.extensions()
.get::<LoggerExampleData>()
.ok_or(ObsidianError::NoneError)?;
let result = ctx.extensions().get::<LoggerExampleData>().unwrap();

dbg!(&result.0);

Expand Down Expand Up @@ -300,11 +295,11 @@ ctx.build(Response::ok().html("<!DOCTYPE html><html><head><link rel=\"shotcut ic
app.use_service(logger_example);

app.scope("params", |router: &mut Router| {
router.get("/test-next-wild/*", |ctx: Context| async {
router.get("/test-next-wild/*", |ctx: Context| async move {
ctx.build("<h1>test next wild</h1>".to_string()).ok()
});

router.get("/*", |ctx: Context| async {
router.get("/*", |ctx: Context| async move {
ctx.build(
"<h1>404 Not Found</h1>"
.to_string()
Expand All @@ -316,5 +311,5 @@ ctx.build(Response::ok().html("<!DOCTYPE html><html><head><link rel=\"shotcut ic

app.use_static_to("/files/", "/assets/");

app.listen(&addr, || {}).await;
app.listen(3000).await
}
4 changes: 3 additions & 1 deletion examples/middleware/logger_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use async_trait::async_trait;
#[cfg(debug_assertions)]
use colored::*;

use obsidian::{context::Context, middleware::Middleware, ContextResult, EndpointExecutor};
use obsidian::{
context::Context, handler::ContextResult, middleware::Middleware, EndpointExecutor,
};

#[derive(Default)]
pub struct LoggerExample {}
Expand Down
Binary file added screenshot/lifecycle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading