example

Usage -- Future

`````rust use athene::handler::Handler; use athene::prelude::*; use std::future::Future; use serde::{Deserialize, Serialize};

[derive(Serialize, Deserialize, Default)]

pub struct User { pub name: String, pub age: i32, }

impl Handler for User { type Responder = Builder; type Future = Box + Unpin + Send>;

fn handle(&self, req: Request) -> Self::Future {
    Box::new(Box::pin(async move {
        let uri = req.uri().path();
        let method = req.method();
        let peer_addr = req.peer_addr();

        let builder = Builder::new();
        builder.text(format!("uri : {}, method: {}, peer_addr: {}",uri,method,peer_addr))
     }))
}

}

impl User { pub fn hello(_: Request) -> impl Future { async { "hello" } }

pub fn get_user(mut req: Request) -> impl Future<Output = impl Responder> {
    async move {
        let user = req.parse::<User>().await?;
        Ok::<_, Error>(json!(&user))
    }
}

pub fn basic_router(r: Router) -> Router {
    r.get("/hello", Self::hello)
    .post("/user", Self::default())
    .post("/get_user", Self::get_user)
}

}

[tokio::main]

pub async fn main() -> Result<()> { let app = athene::new() .router(|r| { r.get("/",|: Request| async { "Hello World" }) }) .router(User::basicrouter) .build();

app.listen("127.0.0.1:7878").await

} `````

Usage MacroController

No need to use athene's validate feature

````rust use athene::prelude::*; use serde::{Deserialize,Serialize};

use validator::Validate;

[derive(Serialize, Deserialize,Validate,Default)]

pub struct UserController { #[validate(email)] pub username: String, #[validate(range(min = 18, max = 20))] pub age: u16, }

// http://127.0.0.1:7878/api/v1/user

[controller(prefix = "api", version = 1, name = "user")]

impl UserController {

#[get("/*/**")]
pub async fn match_any_route(&self, req: Request) -> impl Responder {
    let uri_path = req.uri().path().to_string();
    let method = req.method().to_string();
    (200, format!("uri : {}, method: {}", uri_path, method))
}

#[delete("/{username}/{age}")]
pub async fn delete_by_param(&self, username: String, age: Option<u16>) -> impl Responder {
    (200, format!("username is : {}, and age is : {:?}", username, age))
}

#[get("/get_query_1")]
pub async fn get_query_1(&self, username: String, age: u16) -> impl Responder {
    (200,json!(&Self {
            username,
            age,
        }))
}

#[get("/get_query_2")]
pub async fn get_query_2(&self, request: Request) -> impl Responder {
    let user = request.query::<Self>()?;
    user.validate()?; // User will be validated
    Ok::<_, Error>((200, json!(&user)))
}

// Context-Type : application/json  Or application/x-www-form-urlencoded
// Context-Type : application/msgpack Or application/cbor
#[post("/parse_body")]
#[get("/parse_body")]
async fn parse_body(&self, mut req: Request) -> impl Responder {
    let user = req.parse::<Self>().await?;
    user.validate()?; // User will be validated
    Ok::<_, Error>((
        200,
        format!("username = {} and age = {}", user.username, user.age),
    ))
}

// Context-Type : application/multipart-formdata
#[post("/files")]
async fn files(&self, mut req: Request) -> impl Responder {
    let files = req.files("files").await?;
    let fist_file_name = files[0].name().unwrap();
    let second_file_name = files[1].name().unwrap();
    Ok::<_, Error>((
        200,
        format!(
            "fist {}, second {}",
            fist_file_name, second_file_name
        ),
    ))
}

// Content-Disposition: application/octet-stream
#[get("/download")]
pub async fn download(&self,_req: Request) -> impl Responder {
    let mut res = status!(hyper::StatusCode::OK);
    res.write_file("templates/author.txt", DispositionType::Attachment)?;
    Ok::<_, Error>(res)
}

}

[tokio::main]

pub async fn main() -> Result<()> {

let app = athene::new()
    .router(|r|r.controller(UserController::default()));

let app = app.build();

app.listen("127.0.0.1:7878").await

} ````

Usage BasicController

````rust use athene::prelude::*; use serde::{Deserialize, Serialize};

[derive(Default, Deserialize, Serialize)]

pub struct AtheneController { pub label: String, pub keyword: String, }

impl Controller for AtheneController {

const BASE_PATH: &'static str = "/api/v1/athene";

fn method(&self) -> Vec<ControllerMethod<Self>>
where
    Self: Sized,
{
    ControllerBuilder::new()

    .post("/add", Self::add)
    .delete("/{label}/{keyword}", Self::delete)
    .put("/update", Self::update)
    .get("/get", Self::get)
    .build()
}

}

impl AtheneController {

// http://127.0.0.1:7878/api/v1/athene/add
pub async fn add(&self, mut req: Request) -> impl Responder {
    let obj = req.parse::<Self>().await?;
    Ok::<_, Error>((200, json!(obj)))
}

// http://127.0.0.1:7878/api/v1/athene/
pub async fn delete(&self, mut req: Request) -> impl Responder {
    let lable = req.param::<String>("label")?;
    let keyword = req.param::<String>("keyword")?;

    Ok::<_,Error>((200,format!("lable = {},keyword = {}",lable,keyword)))
}

// http://127.0.0.1:7878/api/v1/athene/update
async fn update(&self, mut req: Request) -> impl Responder {
    let obj = req.parse::<Self>().await?;
    Ok::<_, Error>((200, json!(obj)))
}

// http://127.0.0.1:7878/api/v1/athene/get
async fn get(&self, req: Request) -> impl Responder {
    #[derive(Deserialize, Serialize)]
    struct QueryParam<'a> {
        label: &'a str,
        keyword: &'a str,
    }

    let arg = req.query::<QueryParam>()?;
    let res = json!(&arg);
    Ok::<_, Error>(res)
}

}

[tokio::main]

async fn main() -> Result<(), Error> { let app = athene::new() .router(|r|r.controller(AtheneController::default())) .build();

app.listen("127.0.0.1:7878").await

} ````

Usage Middleware and RouterGroup

````rust use athene::prelude::*; use headers::{authorization::Bearer, Authorization}; use serde::{Deserialize, Serialize}; use tracing::info;

[derive(Serialize, Deserialize)]

pub struct User { pub username: String, pub age: u16, }

pub async fn user_params(mut req: Request) -> impl Responder { let username = req.param("username")?; let age = req.param::("age")?; Ok::<_, Error>((200, json!(&User { username, age }))) }

pub async fn login(mut req: Request) -> impl Responder { if let Ok(user) = req.parse::().await { ( 200, format!("username: {} , age: {} ", user.username, user.age), ) } else { (400, String::from("Bad user format")) } }

pub async fn sign_up(mut req: Request) -> impl Responder { let user = req.parse::().await?; Ok::<_, Error>((200, json!(&user))) }

pub async fn readbody(mut req: Request) -> impl Responder { let body = req.bodybytes().await?; Ok::<_, Error>((200, body)) }

pub async fn bodytostring(mut req: Request) -> impl Responder { let body = req.body_string().await?; Ok::<_, Error>((200, body)) }

pub fn userrouter(r: Router) -> Router { r.group("///user/**/") .get("/{username}/{age}", userparams) .post("/login", login) .post("/signup", signup) .put("/readbody", readbody) .post("/bodytostring", bodytostring) }

// ============================ Middleware Fuction ============================ pub async fn logmiddleware(ctx: Context, next: &'static dyn Next) -> Result { info!( "new request on path: {}", ctx.state.requestunchecked().uri().path() );

let ctx = next.next(ctx).await?;

info!(
    "new response with status: {}",
    ctx.state.response_unchecked().status()
);
Ok(ctx)

}

// ================================ Middleware ====================== struct ApiKeyMiddleware { api_key: String, }

[middleware]

impl ApiKeyMiddleware { async fn next(&self, ctx: Context, chain: &dyn Next) -> Result { if let Some(bearer) = ctx .state .requestunchecked() .header::>() { let token = bearer.0.token(); if token == self.apikey { info!( "Handler {} will be used", ctx.metadata.name.unwrap_or("unknown") ); chain.next(ctx).await } else { info!("Invalid token"); Ok(ctx) } } else { info!("Not Authenticated, "); Ok(ctx) } } }

[tokio::main]

pub async fn main() -> Result<()> { tracing_subscriber::fmt().compact().init();

let app = athene::new()
    .router(user_router)
    .middleware(|m| {
        m.apply(log_middleware, vec!["/"], None).apply(
            ApiKeyMiddleware {
                api_key: "athene".to_string(),
            },
            vec!["/user/login", "/user/sign_up"],
            vec!["/user/read_body","/user/body_to_string"],
        )
    })
    .build();
app.listen("127.0.0.1:7878").await

} ````

Support for WebSocket use feature websocket

````rust use athene::prelude::*;

pub async fn websockethello(req: Request,mut tx: WebSocketSender,mut rx: WebSocketReceiver) -> Result<()> {

while let Some(msg) = rx.receive().await? {
    tx.send(msg).await?;
}
Ok(())

}

// ws://127.0.0.1:7878/ws/world http://www.jsons.cn/websocket/ pub async fn websocketworld(req: Request,mut tx: WebSocketSender,mut rx: WebSocketReceiver) -> Result<()> {

while let Some(msg) = rx.receive().await? {
    tx.send(msg).await?;
}
Ok(())

}

pub fn websocketrouter(r: Router) -> Router { r.group("/ws").ws("/world", websocketworld) }

[tokio::main]

pub async fn main() -> Result<()> { let app = athene::new() .router(|r|{ r

    // ws://127.0.0.1:7878/ws/index  http://www.jsons.cn/websocket/
    .ws("/ws/index", |_req, mut tx, mut rx| async move {

        while let Some(msg) = rx.receive().await? {
            tx.send(msg).await?;
        }
        Ok(())
    })

    // ws://127.0.0.1:7878/ws/hello  http://www.jsons.cn/websocket/
    .post("/ws/hello",new_ws(websocket_hello))
}).
router(websocket_router).
build();

app.listen("127.0.0.1:7878").await

} ````

Support loading static files use feature static_file

````rust use athene::prelude::*; use tera::{Context, Tera}; use serde::Serialize;

pub async fn teratemplate(: Request) -> impl Responder { #[derive(Serialize)] struct Awesome<'a> { url: &'a str, name: &'a str, }

let tera = Tera::new("templates/*").unwrap();
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 love = tera.render("index.html", &ctx).unwrap();
with!(love, "text/html; charset=utf-8")
// html!(love)

}

[tokio::main]

async fn main() -> Result<()> { let app = athene::new() .router(|r|{ r.staticfiles("/template/public/*", "public") .get("/template/teratemplate", tera_template) }).build();

app.listen("127.0.0.1:7878").await

} ````

Usage feature athene_body

If you want to validate parameters, you need to use the validate feature of athene

````rust

use athene::prelude::*; use serde::{Deserialize, Serialize};

use validator::Validate;

[derive(Serialize, Deserialize, Validate, Default)]

pub struct UserController { #[validate(email)] pub username: String, #[validate(range(min = 18, max = 20))] pub age: u16, }

// http://127.0.0.1:7878/api/v1/user

[controller(prefix = "api", version = 1, name = "user")]

impl UserController {

// Context-Type : application/x-www-form-urlencoded
#[post("/body_form")]
#[get("/body_form")] // User will be validated
async fn body_form(&self, user: Form<Self>) -> impl Responder {
    (200, user)
}

// Context-Type : application/json
#[post("/body_json")] // User will be validated
async fn body_json(&self, user: Json<Self>) -> impl Responder {
    (200, user)
}

#[post("/body_form2")]
#[validator(exclude("user"))] // The user parameter will not be validated
async fn body_form2(&self, user: Form<Self>) -> impl Responder {
    let user = user.0;
    (200, Form(user))
}

#[post("/body_json2")]
#[validator(exclude("user"))] // The user parameter will not be validated
async fn body_json2(&self, user: Option<Json<Self>>) -> impl Responder {
    match user {
        Some(user) => (200, user),
        None => (400, Json(Self::default())),
    }
}

}

[tokio::main]

pub async fn main() -> Result<()> { let app = athene::new().router(|r| r.controller(UserController::default())); let app = app.build(); app.listen("127.0.0.1:7878").await } ````