3 个版本
新版本 0.1.2 | 2024 年 8 月 17 日 |
---|---|
0.1.1 | 2024 年 7 月 13 日 |
0.1.0 | 2024 年 7 月 12 日 |
#1172 在 网页编程
每月 256 次下载
用于 2 crates
185KB
5.5K SLoC
一个简单的 Http 服务器库。
基本的 GET 请求
use chuchi::{get, Res};
struct GlobalName(String);
// handle a simple get request
#[get("/")]
fn root(global_name: Res<GlobalName>) -> String {
format!("Hi, this is {}", global_name.0)
}
#[tokio::main]
async fn main() {
let mut server = chuchi::build("0.0.0.0:3000").await
.expect("Failed to parse address");
server.add_resource(GlobalName("fire".into()));
server.add_route(root);
server.run().await.unwrap();
}
更多示例请查看 examples 目录和测试目录。
功能
- json
- fs
- http2 (启用 http 2 支持)
- ws (添加 WebSocket 支持)
- trace
API 示例
#[cfg(feature = "api")]
{
use std::fmt;
use std::sync::{Arc, Mutex};
use chuchi::api::{Request, Method};
use chuchi::api::error::{self, Error as ApiError, StatusCode};
use chuchi::{api, impl_res_extractor, Resource};
use serde::{Serialize, Deserialize};
// -- Type definitions
#[derive(Debug, Clone, Serialize)]
pub enum Error {
Internal(String),
Request(String)
}
impl error::ApiError for Error {
fn from_error(e: ApiError) -> Self {
match e {
ApiError::HeadersMissing(_) |
ApiError::Deserialize(_) => {
Self::Request(e.to_string())
}
e => Self::Internal(e.to_string()),
}
}
fn status_code(&self) -> StatusCode {
match self {
Self::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
Self::Request(_) => StatusCode::BAD_REQUEST
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(self, f)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct NameReq;
#[derive(Debug, Clone, Serialize, Deserialize)]
struct Name {
firstname: String,
lastname: String
}
impl Request for NameReq {
type Response = Name;
type Error = Error;
const PATH: &'static str = "/name";
const METHOD: Method = Method::GET;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct SetNameReq {
name: Name
}
impl Request for SetNameReq {
type Response = ();
type Error = Error;
const PATH: &'static str = "/name";
const METHOD: Method = Method::PUT;
}
// -- implementations
#[derive(Resource)]
struct SharedName(Mutex<Name>);
#[api(NameReq)]
fn get_name(req: NameReq, name: &SharedName) -> Result<Name, Error> {
let lock = name.0.lock().unwrap();
Ok(lock.clone())
}
#[api(SetNameReq)]
fn set_name(req: SetNameReq, name: &SharedName) -> Result<(), Error> {
let mut lock = name.0.lock().unwrap();
*lock = req.name;
Ok(())
}
#[tokio::main]
async fn main() {
let name = SharedName(Mutex::new(Name {
firstname: "Albert".into(),
lastname: "Einstein".into()
}));
let mut server = chuchi::build("0.0.0.0:3000").await
.expect("Failed to parse address");
server.add_resource(name);
server.add_route(get_name);
server.add_route(set_name);
server.run().await.unwrap();
}
}
依赖关系
~6–17MB
~222K SLoC