Skip to content

Commit

Permalink
add template support with askama
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Bonill authored and Sam Bonill committed Oct 17, 2022
1 parent bba30da commit ee9c3e0
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 54 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "graphul"
version = "0.2.2"
version = "0.2.3"
edition = "2021"
license = "MIT"
categories = ["asynchronous", "network-programming", "web-programming::http-server"]
Expand All @@ -17,6 +17,7 @@ readme = "README.md"
hyper = { version = "0.14", features = ["full"] }
tokio = { version = "1", features = ["full"] }
axum = { git= "https://github.com/tokio-rs/axum", version = "0.6.0-rc.2" }
askama = "0.11"
futures = "0.3.19"
num_cpus = "1.13.1"
async-trait = "0.1.52"
Expand Down
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,3 +284,31 @@ async fn main() {
app.run("127.0.0.1:8000").await;
}
```

## Templates

```rust
use graphul::{
http::Methods,
Context, Graphul, template::HtmlTemplate,
};
use askama::Template;

#[derive(Template)]
#[template(path = "hello.html")]
struct HelloTemplate {
name: String,
}

#[tokio::main]
async fn main() {
let mut app = Graphul::new();

app.get("/:name", |c: Context| async move {
let template = HelloTemplate { name: c.params("name") };
HtmlTemplate(template)
});

app.run("127.0.0.1:8000").await;
}
```
4 changes: 0 additions & 4 deletions examples/sqlx-postgres/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ edition = "2021"
publish = false

[dependencies]
#graphul = { git= "https://github.com/graphul-rs/graphul", branch = "main" }
graphul = { path = "../../."}
tokio = { version = "1.0", features = ["full"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

sqlx = { version = "0.5.10", features = ["runtime-tokio-rustls", "any", "postgres"] }
24 changes: 24 additions & 0 deletions examples/sqlx-postgres/src/db.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use std::time::Duration;

use graphul::http::StatusCode;
use sqlx::{postgres::{PgPoolOptions}, Error, Pool, Postgres};

pub async fn db_con() -> Result<Pool<Postgres>, Error> {
let db_uri = std::env::var("DATABASE_URL")
.unwrap_or_else(|_| "postgres://postgres:password@localhost".to_string());

PgPoolOptions::new()
.max_connections(5)
.connect_timeout(Duration::from_secs(3))
.connect(&db_uri)
.await
}

/// Utility function for mapping any error into a `500 Internal Server Error`
/// response.
pub fn internal_error<E>(err: E) -> (StatusCode, String)
where
E: std::error::Error,
{
(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
}
56 changes: 8 additions & 48 deletions examples/sqlx-postgres/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,69 +1,29 @@
//! Example of application using <https://github.com/launchbadge/sqlx>
//!
//! Run with
//!
//! ```not_rust
//! cd examples && cargo run -p example-sqlx-postgres
//! ```
//!
//! Test with curl:
//!
//! ```not_rust
//! curl 127.0.0.1:3000
//! curl -X POST 127.0.0.1:3000
//! ```
mod db;

use graphul::{
Context,
http::{Methods, StatusCode},
Graphul,
};
use sqlx::postgres::{PgPool, PgPoolOptions};
use std::time::Duration;

use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
use sqlx::PgPool;

#[tokio::main]
async fn main() {
tracing_subscriber::registry()
.with(tracing_subscriber::EnvFilter::new(
std::env::var("RUST_LOG").unwrap_or_else(|_| "example_tokio_postgres=debug".into()),
))
.with(tracing_subscriber::fmt::layer())
.init();

let db_uri = std::env::var("DATABASE_URL")
.unwrap_or_else(|_| "postgres://postgres:password@localhost".to_string());

let pool = PgPoolOptions::new()
.max_connections(5)
.connect_timeout(Duration::from_secs(3))
.connect(&db_uri)
.await
.expect("can connect to database");
let pool = db::db_con().await.expect("can connect to database");

// build our application
let mut app = Graphul::share_state(pool);

app.get("/", using_connection_pool_extractor);
app.get("/", using_connection_pool);

app.run("127.0.0.1:3000").await;
}

// we can extract the connection pool with `State` or 'Context'
async fn using_connection_pool_extractor(c: Context<PgPool>,) -> Result<String, (StatusCode, String)> {
// we can extract the connection pool with `State` or `Context`
async fn using_connection_pool(c: Context<PgPool>,) -> Result<String, (StatusCode, String)> {
let pool = c.state();
sqlx::query_scalar("select 'hello world from pg'")
.fetch_one(&*pool)
.fetch_one(pool)
.await
.map_err(internal_error)
}

/// Utility function for mapping any error into a `500 Internal Server Error`
/// response.
fn internal_error<E>(err: E) -> (StatusCode, String)
where
E: std::error::Error,
{
(StatusCode::INTERNAL_SERVER_ERROR, err.to_string())
.map_err(db::internal_error)
}
10 changes: 10 additions & 0 deletions examples/templates/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "example-templates"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
askama = "0.11"
graphul = { path = "../../." }
tokio = { version = "1.0", features = ["full"] }
23 changes: 23 additions & 0 deletions examples/templates/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use graphul::{
http::Methods,
Context, Graphul, template::HtmlTemplate,
};
use askama::Template;

#[derive(Template)]
#[template(path = "hello.html")]
struct HelloTemplate {
name: String,
}

#[tokio::main]
async fn main() {
let mut app = Graphul::new();

app.get("/:name", |c: Context| async move {
let template = HelloTemplate { name: c.params("name") };
HtmlTemplate(template)
});

app.run("127.0.0.1:8000").await;
}
1 change: 1 addition & 0 deletions examples/templates/templates/hello.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Hello, {{ name }}!</h1>
2 changes: 1 addition & 1 deletion src/app.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub const VERSION: &str = "0.2.2";
pub const VERSION: &str = "0.2.3";
2 changes: 2 additions & 0 deletions src/http/response.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pub type Response = axum::response::Response;
pub type Value = serde_json::Value;

pub use axum::response::{Form, Html, Redirect};

#[cfg(test)]
mod tests {
#[test]
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod color;
pub mod http;
mod listen;
pub mod middleware;
pub mod template;

use std::convert::Infallible;
use std::net::SocketAddr;
Expand Down
21 changes: 21 additions & 0 deletions src/template.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use askama::Template;
use axum::response::{Html, IntoResponse, Response};
use hyper::StatusCode;

pub struct HtmlTemplate<T>(pub T);

impl<T> IntoResponse for HtmlTemplate<T>
where
T: Template,
{
fn into_response(self) -> Response {
match self.0.render() {
Ok(html) => Html(html).into_response(),
Err(err) => (
StatusCode::INTERNAL_SERVER_ERROR,
format!("Failed to render template. Error: {}", err),
)
.into_response(),
}
}
}

0 comments on commit ee9c3e0

Please sign in to comment.