````rust use askama::Template;
use athene::DispositionType; use athene::{Error, Middleware, Next, Request, Response, Result, StatusCode}; use route::fifth::fifth_router; use serde::{Deserialize, Serialize}; use std::pin::Pin; use tera::{Context, Tera};
pub struct User { name: String, age: i32, }
// http://127.0.0.1:8081/api/hello/rust-lang pub async fn hello(req: Request) -> Result { let name: String = req.param("name").unwrap(); let mut res = Response::new(); res.text(name)?; Ok(res) }
// http://127.0.0.1:8081/welcome?name=admin2029&age=21
pub async fn welcome(req: Request) -> Result {
let user = req.query::
// Context-Type : application/json
pub async fn login(req: Request) -> Result {
let mut req = req;
let user = req.parse::
// Context-Type : application/x-www-form-urlencoded pub async fn form_encode(req: Request) -> Result{ #[derive(Deserialize,Serialize)] struct Rust { version: String, edition: String, }
let mut req = req;
let rust = req.parse::<Rust>().await?;
let mut res = Response::new();
res.json(&rust)?;
Ok(res)
}
// Context-Type : application/multipart-formdata
pub async fn upload(req: Request) -> Result { let mut req = req; let info = req.upload("file", "temp").await?; use athene::IntoResponse; info.response() }
// Context-Type : application/multipart-formdata
pub async fn uploads(req: Request) -> Result { let mut req = req; let info = req.uploads("files", "temp").await?; use athene::IntoResponse; info.response() }
// Content-Disposition: application/octet-stream
pub async fn download(req: Request) -> Result { let mut res = Response::new(); res.writefile("templates/author.txt", DispositionType::Attachment)?; Ok(res) }
// Response redirect pub async fn index(req: Request) -> Result { println!("redirect handler"); Response::redirect(StatusCode::MOVEDPERMANENTLY, "/api/rust") }
// Response redirect pub async fn permanent(req: Request) -> Result { Response::redirect(StatusCode::PERMANENTREDIRECT, "/api/code") }
// Response redirect pub async fn temporary(req: Request) -> Result { Response::redirect(StatusCode::TEMPORARYREDIRECT, "/api/world") }
// Content-Location pub async fn location(_req: Request) -> Result { Response::location("/") }
// askama template pub async fn askamatemplate(: Request) -> Result { #[derive(Serialize, Hash, Eq, PartialEq, Clone, Template)] #[template(path = "favorite.html")] pub struct Favorite<'a> { title: &'a str, time: i32, }
let love = Favorite {
title: "rust_lang",
time: 1314,
};
let mut res = Response::new();
let love = love.render()?;
res.html(love)?;
Ok(res)
}
// tera template pub async fn teratemplate(: Request) -> Result { #[derive(Serialize)] struct Awesome<'a> { url: &'a str, name: &'a str, }
let tera = Tera::new("templates/*")?;
let mut ctx = Context::new();
ctx.insert("title", "Welcome to rust-lang world!");
ctx.insert(
"product",
&vec![
Awesome {
url: "https://github.com/rust-lang",
name: "rust-lang",
},
Awesome {
url: "https://github.com/lapce/lapce",
name: "lapce",
},
],
);
let mut res = Response::new();
let love = tera.render("index.html", &ctx)?;
res.html(love)?;
Ok(res)
}
// Define a middleware
pub struct Logger;
impl Middleware for Logger { async fn handle(self: Pin<&Self>, request: Request, next: Next<'_>) -> Result {
if request.uri().path().starts_with("/auth") && request.method().eq("GET"){
let res = next.next(request).await?;
return Ok(res);
} else {
use athene::IntoResponse;
"Logger middleware is used".response()
}
}
}
pub(crate) mod route {
pub(crate) mod first {
use crate::{index, permanent, temporary, welcome};
pub(crate) fn first_router() -> athene::Router {
let mut router = athene::new();
router.get("/", index);
router.get("/permanent", permanent);
router.get("/temporary", temporary);
router.get("/welcome", welcome);
router
}
}
pub(crate) mod second {
use crate::{askama_template, location, route::first::first_router, tera_template};
#[cfg(feature = "file")]
use crate::{download, upload, uploads};
pub(crate) fn second_router() -> athene::Router {
let mut router = first_router();
#[cfg(feature = "file")]
router.post("/upload", upload);
#[cfg(feature = "file")]
router.post("/uploads", uploads);
#[cfg(feature = "file")]
router.get("/download", download);
router.get("/location", location);
router.get("/askama_template", askama_template);
router.get("/tera_template", tera_template);
router
}
}
pub(crate) mod third {
use super::second::second_router;
use athene::{Request, StatusCode};
pub(crate) fn third_router() -> athene::Router {
let mut router = second_router();
router.group("/closure", |base| {
base.get("/str", |_req| async { "closure str" });
base.post("/string", |_| async { String::from("closure string") });
base.put("/vec/", |_| async { [1, 3, 5, 7, 9].to_vec() });
base.delete("/status", |_| async { StatusCode::NO_CONTENT });
base.options("/empty", |_| async {});
base.head("/empty/bracket", |_| async { () });
base.put("/remote_addr", |req: Request| async move {
let addr = req.remote_addr().unwrap();
let addr = addr.to_string();
addr
});
base.patch("/remote_ip", |req: Request| async move {
let ip = req.ip().unwrap();
let ip = ip.to_string();
ip
});
base.post("/status/value", |_| async {
(StatusCode::NOT_FOUND, "welcome to my world")
});
});
router
}
}
pub(crate) mod fifth {
use super::third::third_router;
use crate::{hello, login,Logger,form_encode};
pub(crate) fn fifth_router() -> athene::Router {
let mut router = third_router();
router.group("/api", |base| {
base.get("/hello/{name}", hello);
base.get("/world", |_|async {
"world"
});
base.get("/code", |_| async {
"code handler"
});
base.get("/rust", |_| async {
"welcome to rust_lang world"
});
base.group("/user", |user| {
user.post("/", login);
user.post("/form_encode",form_encode);
});
});
router.middleware(Logger).group("/auth", |base| {
base.get("/success",|req: athene::Request| async move {
format!("{} {}",req.uri().path(),req.method())
});
base.post("/failed",|_| async {
"failed"
});
});
router
}
}
}
pub async fn main() -> Result<(), Error> { let router = fifth_router(); router.listen("127.0.0.1:8081").await } ````
````html
````
````html
{{time}}
````