faithea

Crates.iofaithea
lib.rsfaithea
version0.1.6
created_at2025-12-24 04:56:52.259141+00
updated_at2026-01-10 09:22:38.474882+00
descriptionA HTTP framework
homepage
repositoryhttps://github.com/bigoldcat123/graduation
max_upload_size
id2002747
size173,928
Dale Lowe (bigoldcat123)

documentation

README

Example

  1. Hello World
#[get("/")]
async fn hello_world() {
    "Hello,World"
}
#[tokio::main(flavor = "current_thread")]
async fn main() {
    HttpServer::builder()
        .mount("/", handlers!(hello_world))
        .build()
        .start()
        .await;
}
  1. static file mapping
#[get("/**")]
async fn static_file_map() {
    static_map(&_req, "/path/to/directory").await
}
  1. return a file
#[get("/file")]
async fn file() {
    StaticFile("/path/to/file")
}
  1. search_param eg. /searchParam?name=hello&age=100
#[get("/searchParam")]
async fn search_param(
    #[search_param] name: usize,
    #[search_param] age: String,
) {
    println!("name: {}, age:{}, }",name,age,);
    "good"
}
  1. path_param
#[get("/pathParam/{name}/{age}")]
async fn path_params(
    name: String,
    age: usize,
) {
    println!("name: {}, age:{}",name,age);
    res_modifiers!("")
}
  1. Json body of request and response
// Serialize for request body
// Deserialize for response body
#[derive(Serialize, Deserialize)]
struct Stu {
    name: String,
    age: i32,
}
#[post("/json")]
async fn search_params_and_path_params_and_json(
    stu: Json<Stu>,
) {
    stu
}
  1. multipart form data

derive from MultipartData

the type of field shoule impl TryFrom<Part>

#[derive(MultipartData, Debug)]
struct StuInfo {
    pub name: String,
    pub age: i32,
    pub merried: Option<bool>,
    pub profile: MultiPartFile,
}

#[post("/multipart")]
async fn multipart(data: Multipart<StuInfo>) {
    let data = data.into_inner();
    println!(
        "{:?} {:?} {:?} {:?}",
        data.age, data.name, data.profile, data.merried
    );
    "ok"
}
  1. add guard guard will execute before the handlers
async fn guard_ok(req:HttpRequest) -> Result<HttpRequest,HttpResponse> {
  Ok(req)
}
async fn guard_err(req:HttpRequest) -> Result<HttpRequest,HttpResponse> {
  Err(HttpResponse::not_found())
}

HttpServer::builder()
    .mount("/", handlers!(hello_world))
    .guard("/**", async |e:HttpRequest| {
        println!("new req -> ");
        Ok(e)
    })
    .guard("/a",guard_ok)
    .guard("/b",guard_err)
    .build()
    .start()
    .await;
  1. make anything converted from request
#[derive(Debug, Serialize, Deserialize)]
struct Stu {
    name: String,
    age: i32,
}
impl TryFrom<&mut HttpRequest> for Stu {
    type Error = String;
    fn try_from(value: &mut HttpRequest) -> Result<Self, Self::Error> {
        Ok(Stu {
            name: "from req".into(),
            age: 111,
        })
    }
}
#[post("/fromRequest")]
async fn fromRequest(stu:FromRequest<Stu>) {

    serde_json::to_string(&stu.into_inner()).unwrap()
}

Tips

  1. make your type compatible with searchParam and pathParam
impl TryConvertFrom<Option<&String>> for String {
    fn try_convert_from(value: Option<&String>) -> Result<Self, FuError> {
        if let Some(value) = value {
            Ok(value.to_string())
        } else {
            Err("missing value".into())
        }
    }
}
  1. make your struct compatible with returning from handler. implememt HttpResponseModifier for your struct
pub trait HttpResponseModifier {
    fn modify<'a>(
        &'a self,
        res: &'a mut HttpResponse,
    ) -> std::pin::Pin<Box<dyn Future<Output = Result<(), FuError>> + 'a + Send + Sync>>;
}
impl HttpResponseModifier for MyStruct {
    fn modify<'a>(
        &'a self,
        res: &'a mut HttpResponse,
    ) -> std::pin::Pin<Box<dyn Future<Output = Result<(), FuError>> + 'a + Send + Sync>> {
        Box::pin(async move {
            /// your code to modify response
            Ok(())
        })
    }
}
  1. using modifiers!() to return multiple modifier

  2. you can have an access to HttpRequest in any handler through _req

  3. make your struct be the field in a multipartData just impl the std TryFrom with error = String

#[derive(Debug)]
struct A{

}
impl TryFrom<Part> for A {
    type Error = FuError;
    fn try_from(value: Part) -> Result<Self, Self::Error> {
        Ok(Self{})
    }
}

#[derive(MultipartData, Debug)]
struct StuInfo {
    pub name: Vec<A>,
    pub age: i32,
    pub merried: Option<bool>,
    pub profile: Vec<MultiPartFile>,
}
Commit count: 118

cargo fmt