Browse Source

[xitca-web]update dep. (#7318)

* update dep.

* update dep.
fakeshadow 3 năm trước cách đây
mục cha
commit
04d171e3f7

+ 17 - 19
frameworks/Rust/xitca-web/Cargo.toml

@@ -12,26 +12,25 @@ name = "xitca-web-diesel"
 path = "./src/main_diesel.rs"
 
 [dependencies]
-xitca-http = "0.1"
-xitca-http-codegen = "0.1"
+xitca-http = { version = "0.1", features = ["util-service"] }
 xitca-server = "0.1"
 xitca-service = "0.1"
-xitca-web = "0.1"
+xitca-web = { version = "0.1", features = ["json"] }
 xitca-postgres = "0.1"
 
-ahash = { version = "0.7.6", features = ["compile-time-rng"] }
-atoi = "0.4.0"
+ahash = { version = "0.7.1", features = ["compile-time-rng"] }
+atoi = "1.0.0"
 core_affinity = "0.5.10"
-diesel = { version = "2", default-features = false }
+diesel = { version = "2.0.0-rc.0", default-features = false, features = ["i-implement-a-third-party-backend-and-opt-into-breaking-changes"]}
 diesel-async = { version = "0.1.0", features = ["postgres"], default-features = false }
 futures-util = { version = "0.3.18", default-features = false, features = ["alloc"] }
-mimalloc = { version = "0.1.27", default-features = false }
-rand = { version = "0.8", default-features = false, features = ["min_const_gen", "small_rng"] }
+mimalloc = { version = "0.1.29", default-features = false }
+rand = { version = "0.8.5", default-features = false, features = ["min_const_gen", "small_rng"] }
 sailfish = "0.3.4"
 serde = "1"
-simd-json = "0.4.8"
+simd-json = "0.4.15"
 tang-rs = "0.2"
-tokio = { version = "1.14", features = ["macros", "rt"] }
+tokio = { version = "1.18.0", features = ["macros", "rt"] }
 
 [profile.release]
 lto = true
@@ -40,13 +39,12 @@ codegen-units = 1
 panic = "abort"
 
 [patch.crates-io]
-xitca-http = { git = "https://github.com/fakeshadow/xitca-web.git", rev = "e1debcd4630196669923f94c7693e5519f34db52" }
-xitca-http-codegen = { git = "https://github.com/fakeshadow/xitca-web.git", rev = "e1debcd4630196669923f94c7693e5519f34db52" }
-xitca-io = { git = "https://github.com/fakeshadow/xitca-web.git", rev = "e1debcd4630196669923f94c7693e5519f34db52" }
-xitca-postgres = { git = "https://github.com/fakeshadow/xitca-web.git", rev = "e1debcd4630196669923f94c7693e5519f34db52" }
-xitca-server = { git = "https://github.com/fakeshadow/xitca-web.git", rev = "e1debcd4630196669923f94c7693e5519f34db52" }
-xitca-service = { git = "https://github.com/fakeshadow/xitca-web.git", rev = "e1debcd4630196669923f94c7693e5519f34db52" }
-xitca-web = { git = "https://github.com/fakeshadow/xitca-web.git", rev = "e1debcd4630196669923f94c7693e5519f34db52" }
+xitca-http = { git = "https://github.com/HFQR/xitca-web.git", rev = "ee542a12f07b9aec28c98688412ef432e467453e" }
+xitca-io = { git = "https://github.com/HFQR/xitca-web.git", rev = "ee542a12f07b9aec28c98688412ef432e467453e" }
+xitca-postgres = { git = "https://github.com/HFQR/xitca-web.git", rev = "ee542a12f07b9aec28c98688412ef432e467453e" }
+xitca-server = { git = "https://github.com/HFQR/xitca-web.git", rev = "ee542a12f07b9aec28c98688412ef432e467453e" }
+xitca-service = { git = "https://github.com/HFQR/xitca-web.git", rev = "ee542a12f07b9aec28c98688412ef432e467453e" }
+xitca-unsafe-collection = { git = "https://github.com/HFQR/xitca-web.git", rev = "ee542a12f07b9aec28c98688412ef432e467453e" }
+xitca-web = { git = "https://github.com/HFQR/xitca-web.git", rev = "ee542a12f07b9aec28c98688412ef432e467453e" }
 
-diesel = { git = "https://github.com/fakeshadow/diesel.git", rev = "ed2ceeb377c986c1013c6261e44658e3f43725d3" }
-diesel-async = { git = "https://github.com/fakeshadow/diesel_async.git", rev = "dc2e77677299aa6b406353960a9eab7a7bd5bc72" }
+diesel-async = { git = "https://github.com/weiznich/diesel_async.git", rev = "d74eefd18b7e738b02aa2fa5f8bfd934b1d4db95" }

+ 10 - 8
frameworks/Rust/xitca-web/src/db.rs

@@ -3,7 +3,6 @@ use std::{cell::RefCell, error::Error, fmt::Write};
 use ahash::AHashMap;
 use futures_util::stream::{FuturesUnordered, StreamExt, TryStreamExt};
 use rand::{rngs::SmallRng, Rng, SeedableRng};
-use tokio::pin;
 use xitca_postgres::{Postgres, Statement, ToSql};
 
 use super::ser::{Fortune, Fortunes, World};
@@ -29,7 +28,7 @@ impl Drop for Client {
 }
 
 pub async fn create(config: &str) -> Client {
-    let (client, conn) = Postgres::new(config).connect().await.unwrap();
+    let (client, conn) = Postgres::new(config.to_string()).connect().await.unwrap();
 
     tokio::task::spawn_local(async move {
         let _ = conn.await;
@@ -82,9 +81,14 @@ type DbResult<T> = Result<T, Box<dyn Error>>;
 
 impl Client {
     async fn query_one_world(&self, id: i32) -> DbResult<World> {
-        let stream = self.client.query_raw(&self.world, &[&id]).await?;
-        pin!(stream);
-        let row = stream.next().await.unwrap()?;
+        let row = self
+            .client
+            .query_raw(&self.world, &[&id])
+            .await?
+            .next()
+            .await
+            .unwrap()?;
+
         Ok(World::new(row.get(0), row.get(1)))
     }
 
@@ -148,13 +152,11 @@ impl Client {
 
         items.push(Fortune::new(0, "Additional fortune added at request time."));
 
-        let stream = self
+        let mut stream = self
             .client
             .query_raw::<_, &[i32; 0]>(&self.fortune, &[])
             .await?;
 
-        pin!(stream);
-
         while let Some(row) = stream.try_next().await? {
             items.push(Fortune::new(row.get(0), row.get::<_, String>(1)));
         }

+ 127 - 126
frameworks/Rust/xitca-web/src/main.rs

@@ -1,5 +1,3 @@
-#![feature(generic_associated_types, type_alias_impl_trait)]
-
 #[global_allocator]
 static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
 
@@ -8,178 +6,181 @@ mod ser;
 mod util;
 
 use std::{
+    cell::{RefCell, RefMut},
     convert::Infallible,
     error::Error,
-    future::ready,
-    io,
+    fmt::Debug,
     sync::{Arc, Mutex},
 };
 
-use serde::Serialize;
 use xitca_http::{
     body::ResponseBody,
-    bytes::Bytes,
+    bytes::BufMutWriter,
+    bytes::BytesMut,
     config::HttpServiceConfig,
     h1::RequestBody,
     http::{
         self,
+        const_header_value::{JSON, TEXT, TEXT_HTML_UTF8},
         header::{CONTENT_TYPE, SERVER},
-        IntoResponse, Method,
+        IntoResponse,
+    },
+    request,
+    util::{
+        middleware::TcpConfig,
+        service::{
+            context::{object::ContextObjectConstructor, Context, ContextBuilder},
+            route::get,
+            GenericRouter,
+        },
     },
-    util::service::Route,
     HttpServiceBuilder,
 };
-use xitca_server::Builder;
+use xitca_service::{fn_service, BuildServiceExt, Service};
 
 use self::db::Client;
 use self::ser::Message;
-use self::util::{
-    internal, not_found, AppState, QueryParse, JSON_HEADER_VALUE, SERVER_HEADER_VALUE,
-    TEXT_HEADER_VALUE,
-};
-
-type Request = xitca_http::Request<RequestBody>;
+use self::util::{QueryParse, SERVER_HEADER_VALUE};
 
 type Response = http::Response<ResponseBody>;
+type Request = request::Request<RequestBody>;
+type State = AppState<Client>;
+
+type Ctx<'a> = Context<'a, Request, State>;
 
-#[tokio::main(flavor = "current_thread")]
-async fn main() -> io::Result<()> {
-    let cores = core_affinity::get_core_ids().unwrap_or_else(Vec::new);
+fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
+    let cores = core_affinity::get_core_ids().unwrap_or_default();
     let cores = Arc::new(Mutex::new(cores));
 
-    let factory = || {
-        let http = Http {
-            config: "postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world",
-        };
+    let db_url = "postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world";
 
+    let builder = || {
         let config = HttpServiceConfig::new()
             .disable_vectored_write()
             .max_request_headers::<8>();
 
-        let route = Route::new(http).methods([Method::GET]);
+        let router = GenericRouter::with_custom_object::<ContextObjectConstructor<_, _>>()
+            .insert("/plaintext", get(fn_service(plain_text)))
+            .insert("/json", get(fn_service(json)))
+            .insert("/db", get(fn_service(db)))
+            .insert("/fortunes", get(fn_service(fortunes)))
+            .insert("/queries", get(fn_service(queries)))
+            .insert("/updates", get(fn_service(updates)))
+            .enclosed_fn(middleware_fn);
+
+        let service = ContextBuilder::new(|| async {
+            let client = db::create(db_url).await;
+            Ok::<_, Infallible>(State::new(client))
+        })
+        .service(router);
+
+        let tcp_config = TcpConfig::new().set_nodelay(true);
 
-        HttpServiceBuilder::h1(route).config(config)
+        HttpServiceBuilder::h1(service)
+            .config(config)
+            .enclosed(tcp_config)
     };
 
-    Builder::new()
-        .on_worker_start(move || {
-            if let Some(core) = cores.lock().unwrap().pop() {
-                core_affinity::set_for_current(core);
-            }
-            ready(())
-        })
-        .bind("xitca-web", "0.0.0.0:8080", factory)?
-        .build()
-        .await
-}
+    let task = async {
+        xitca_server::Builder::new()
+            .on_worker_start(move || {
+                if let Some(core) = cores.lock().unwrap().pop() {
+                    core_affinity::set_for_current(core);
+                }
+                async {}
+            })
+            .bind("xitca-web", "0.0.0.0:8080", builder)?
+            .build()
+            .await
+            .map_err(Into::into)
+    };
 
-#[derive(Clone)]
-struct Http {
-    config: &'static str,
+    tokio::runtime::Builder::new_current_thread()
+        .enable_all()
+        .build()?
+        .block_on(task)
 }
 
-struct HttpService {
-    state: AppState<Client>,
+async fn middleware_fn<S, E>(service: &S, req: Ctx<'_>) -> Result<Response, Infallible>
+where
+    S: for<'r, 'c> Service<Ctx<'c>, Response = Response, Error = E>,
+    E: Debug,
+{
+    let mut res = service.call(req).await.unwrap();
+    res.headers_mut().append(SERVER, SERVER_HEADER_VALUE);
+    Ok(res)
 }
 
-#[xitca_http_codegen::service_impl]
-impl HttpService {
-    async fn new_service(http: &Http, _: ()) -> Result<Self, ()> {
-        let client = db::create(http.config).await;
-
-        Ok(HttpService {
-            state: AppState::new(client),
-        })
-    }
-
-    async fn ready(&self) -> Result<(), Infallible> {
-        Ok(())
-    }
-
-    async fn call(&self, req: Request) -> Result<Response, Infallible> {
-        match req.uri().path() {
-            "/plaintext" => self.plain_text(req),
-            "/json" => self.json(req),
-            "/db" => self.db(req).await,
-            "/fortunes" => self.fortunes(req).await,
-            "/queries" => self.queries(req).await,
-            "/updates" => self.updates(req).await,
-            _ => not_found(),
-        }
-    }
+async fn plain_text(ctx: Ctx<'_>) -> Result<Response, Box<dyn Error>> {
+    let (req, _) = ctx.into_parts();
+    let mut res = req.into_response("Hello, World!");
+    res.headers_mut().append(CONTENT_TYPE, TEXT);
+    Ok(res)
 }
 
-impl HttpService {
-    fn plain_text(&self, req: Request) -> Result<Response, Infallible> {
-        let mut res = req.into_response("Hello, World!");
-
-        res.headers_mut().append(SERVER, SERVER_HEADER_VALUE);
-        res.headers_mut().append(CONTENT_TYPE, TEXT_HEADER_VALUE);
-
-        Ok(res)
-    }
+async fn json(ctx: Ctx<'_>) -> Result<Response, Box<dyn Error>> {
+    let (req, state) = ctx.into_parts();
+    _json(req, state, &Message::new())
+}
 
-    #[inline]
-    fn json(&self, req: Request) -> Result<Response, Infallible> {
-        self._json(req, &Message::new())
-    }
+async fn db(ctx: Ctx<'_>) -> Result<Response, Box<dyn Error>> {
+    let (req, state) = ctx.into_parts();
+    let world = state.client().get_world().await?;
+    _json(req, state, &world)
+}
 
-    async fn db(&self, req: Request) -> Result<Response, Infallible> {
-        match self.state.client().get_world().await {
-            Ok(ref world) => self._json(req, world),
-            Err(_) => internal(),
-        }
-    }
+async fn fortunes(ctx: Ctx<'_>) -> Result<Response, Box<dyn Error>> {
+    let (req, state) = ctx.into_parts();
+    use sailfish::TemplateOnce;
+    let fortunes = state.client().tell_fortune().await?.render_once()?;
+    let mut res = req.into_response(fortunes);
+    res.headers_mut().append(CONTENT_TYPE, TEXT_HTML_UTF8);
+    Ok(res)
+}
 
-    async fn fortunes(&self, req: Request) -> Result<Response, Infallible> {
-        match self._fortunes().await {
-            Ok(body) => {
-                let mut res = req.into_response(body);
+async fn queries(ctx: Ctx<'_>) -> Result<Response, Box<dyn Error>> {
+    let (req, state) = ctx.into_parts();
+    let num = req.uri().query().parse_query();
+    let worlds = state.client().get_worlds(num).await?;
+    _json(req, state, worlds.as_slice())
+}
 
-                res.headers_mut().append(SERVER, util::SERVER_HEADER_VALUE);
-                res.headers_mut()
-                    .append(CONTENT_TYPE, util::HTML_HEADER_VALUE);
+async fn updates(ctx: Ctx<'_>) -> Result<Response, Box<dyn Error>> {
+    let (req, state) = ctx.into_parts();
+    let num = req.uri().query().parse_query();
+    let worlds = state.client().update(num).await?;
+    _json(req, state, worlds.as_slice())
+}
 
-                Ok(res)
-            }
-            Err(_) => internal(),
-        }
-    }
+fn _json<S>(req: Request, state: &State, value: &S) -> Result<Response, Box<dyn Error>>
+where
+    S: ?Sized + serde::Serialize,
+{
+    let mut buf = state.write_buf();
+    simd_json::to_writer(BufMutWriter(&mut *buf), value).unwrap();
+    let body = buf.split().freeze();
+    let mut res = req.into_response(body);
+    res.headers_mut().append(CONTENT_TYPE, JSON);
+    Ok(res)
+}
 
-    async fn queries(&self, req: Request) -> Result<Response, Infallible> {
-        let num = req.uri().query().parse_query();
-        match self.state.client().get_worlds(num).await {
-            Ok(worlds) => self._json(req, worlds.as_slice()),
-            Err(_) => internal(),
-        }
-    }
+struct AppState<C> {
+    client: C,
+    // a re-usable buffer for write response data.
+    write_buf: RefCell<BytesMut>,
+}
 
-    async fn updates(&self, req: Request) -> Result<Response, Infallible> {
-        let num = req.uri().query().parse_query();
-        match self.state.client().update(num).await {
-            Ok(worlds) => self._json(req, worlds.as_slice()),
-            Err(_) => internal(),
-        }
+impl<C> AppState<C> {
+    fn new(client: C) -> Self {
+        let write_buf = RefCell::new(BytesMut::new());
+        Self { client, write_buf }
     }
 
-    async fn _fortunes(&self) -> Result<Bytes, Box<dyn Error>> {
-        use sailfish::TemplateOnce;
-        let fortunes = self.state.client().tell_fortune().await?.render_once()?;
-        Ok(fortunes.into())
+    fn write_buf(&self) -> RefMut<'_, BytesMut> {
+        self.write_buf.borrow_mut()
     }
 
-    fn _json<S>(&self, req: Request, value: &S) -> Result<Response, Infallible>
-    where
-        S: ?Sized + Serialize,
-    {
-        let mut writer = self.state.writer();
-        simd_json::to_writer(&mut writer, value).unwrap();
-        let body = writer.take();
-
-        let mut res = req.into_response(body);
-        res.headers_mut().append(SERVER, SERVER_HEADER_VALUE);
-        res.headers_mut().append(CONTENT_TYPE, JSON_HEADER_VALUE);
-
-        Ok(res)
+    fn client(&self) -> &C {
+        &self.client
     }
 }

+ 56 - 93
frameworks/Rust/xitca-web/src/main_diesel.rs

@@ -9,133 +9,96 @@ mod schema;
 mod ser;
 mod util;
 
-use std::{convert::Infallible, error::Error, io};
+use std::convert::Infallible;
 
 use serde::Serialize;
 use xitca_web::{
-    dev::{bytes::Bytes, fn_service},
-    http::{
-        header::{CONTENT_TYPE, SERVER},
-        Method,
-    },
+    dev::Service,
+    handler::{handler_service, html::Html, json::Json, state::StateRef, uri::UriRef, Responder},
+    http::header::SERVER,
     request::WebRequest,
+    response::WebResponse,
+    route::get,
     App, HttpServer,
 };
 
 use self::db_diesel::{create, DieselPool};
 use self::ser::Message;
-use self::util::{
-    internal, not_found, AppState, HandleResult, QueryParse, JSON_HEADER_VALUE,
-    SERVER_HEADER_VALUE, TEXT_HEADER_VALUE,
-};
+use self::util::{QueryParse, SERVER_HEADER_VALUE};
+
+type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
 
-type State = AppState<DieselPool>;
+type Request<'a> = WebRequest<'a, DieselPool>;
 
 #[tokio::main(flavor = "current_thread")]
-async fn main() -> io::Result<()> {
+async fn main() -> Result<(), Error> {
     let config = "postgres://benchmarkdbuser:benchmarkdbpass@tfb-database/hello_world";
 
     HttpServer::new(move || {
-        App::with_async_state(move || async move {
-            let pool = create(config).await.unwrap();
-            Ok::<_, Infallible>(AppState::new(pool))
-        })
-        .service(fn_service(handle))
+        App::with_async_state(move || async { Ok::<_, Infallible>(create(config).await.unwrap()) })
+            .at("/plaintext", get(handler_service(plain_text)))
+            .at("/json", get(handler_service(json)))
+            .at("/db", get(handler_service(db)))
+            .at("/fortunes", get(handler_service(fortunes)))
+            .at("/queries", get(handler_service(queries)))
+            .at("/updates", get(handler_service(updates)))
+            .enclosed_fn(middleware_fn)
+            .finish()
     })
-    .disable_vectored_write()
-    .max_request_headers::<8>()
     .bind("0.0.0.0:8080")?
     .run()
     .await
+    .map_err(Into::into)
 }
 
-async fn handle(req: &mut WebRequest<'_, State>) -> HandleResult {
-    let inner = req.req_mut();
-
-    match (inner.method(), inner.uri().path()) {
-        (&Method::GET, "/plaintext") => plain_text(req),
-        (&Method::GET, "/json") => json(req),
-        (&Method::GET, "/db") => db(req).await,
-        (&Method::GET, "/fortunes") => fortunes(req).await,
-        (&Method::GET, "/queries") => queries(req).await,
-        (&Method::GET, "/updates") => updates(req).await,
-        _ => not_found(),
-    }
-}
-
-async fn db(req: &mut WebRequest<'_, State>) -> HandleResult {
-    match req.state().client().get_world().await {
-        Ok(world) => _json(req, &world),
-        Err(_) => internal(),
-    }
-}
-
-async fn fortunes(req: &mut WebRequest<'_, State>) -> HandleResult {
-    match _fortunes(req.state().client()).await {
-        Ok(body) => {
-            let mut res = req.as_response(body);
+async fn middleware_fn<S, E>(service: &S, mut ctx: Request<'_>) -> Result<WebResponse, Infallible>
+where
+    S: for<'r> Service<Request<'r>, Response = Result<WebResponse, Error>, Error = E>,
+    E: for<'r> Responder<Request<'r>, Output = WebResponse>,
+{
+    let mut res = match service.call(ctx.reborrow()).await {
+        Ok(Ok(res)) => res,
+        Ok(Err(err)) => err.respond_to(ctx).await,
+        Err(err) => err.respond_to(ctx).await,
+    };
 
-            res.headers_mut().append(SERVER, util::SERVER_HEADER_VALUE);
-            res.headers_mut()
-                .append(CONTENT_TYPE, util::HTML_HEADER_VALUE);
+    res.headers_mut().append(SERVER, SERVER_HEADER_VALUE);
 
-            Ok(res)
-        }
-        Err(_) => internal(),
-    }
+    Ok(res)
 }
 
-async fn queries(req: &mut WebRequest<'_, State>) -> HandleResult {
-    let num = req.req_mut().uri().query().parse_query();
-
-    match req.state().client().get_worlds(num).await {
-        Ok(worlds) => _json(req, worlds.as_slice()),
-        Err(_) => internal(),
-    }
+async fn plain_text(_: &Request<'_>) -> Result<&'static str, Error> {
+    Ok("Hello, World!")
 }
 
-async fn updates(req: &mut WebRequest<'_, State>) -> HandleResult {
-    let num = req.req_mut().uri().query().parse_query();
+async fn json(_: &Request<'_>) -> Result<Json<impl Serialize>, Error> {
+    Ok(Json(Message::new()))
+}
 
-    match req.state().client().update(num).await {
-        Ok(worlds) => _json(req, worlds.as_slice()),
-        Err(_) => internal(),
-    }
+async fn db(StateRef(pool): StateRef<'_, DieselPool>) -> Result<Json<impl Serialize>, Error> {
+    pool.get_world().await.map(Json)
 }
 
-#[inline]
-async fn _fortunes(pool: &DieselPool) -> Result<Bytes, Box<dyn Error + Send + Sync + 'static>> {
+async fn fortunes(StateRef(pool): StateRef<'_, DieselPool>) -> Result<Html<String>, Error> {
     use sailfish::TemplateOnce;
     let fortunes = pool.tell_fortune().await?.render_once()?;
-    Ok(fortunes.into())
+    Ok(Html(fortunes))
 }
 
-fn plain_text<D>(req: &mut WebRequest<'_, D>) -> HandleResult {
-    let mut res = req.as_response(Bytes::from_static(b"Hello, World!"));
-
-    res.headers_mut().append(SERVER, SERVER_HEADER_VALUE);
-    res.headers_mut().append(CONTENT_TYPE, TEXT_HEADER_VALUE);
-
-    Ok(res)
-}
-
-#[inline(always)]
-fn json<D>(req: &mut WebRequest<'_, AppState<D>>) -> HandleResult {
-    _json(req, &Message::new())
+async fn queries(
+    StateRef(pool): StateRef<'_, DieselPool>,
+    UriRef(uri): UriRef<'_>,
+) -> Result<Json<impl Serialize>, Error> {
+    let num = uri.query().parse_query();
+    let worlds = pool.get_worlds(num).await?;
+    Ok(Json(worlds))
 }
 
-#[inline]
-fn _json<S, D>(req: &mut WebRequest<'_, AppState<D>>, value: &S) -> HandleResult
-where
-    S: ?Sized + Serialize,
-{
-    let mut writer = req.state().writer();
-    simd_json::to_writer(&mut writer, value).unwrap();
-    let body = writer.take();
-
-    let mut res = req.as_response(body);
-    res.headers_mut().append(SERVER, SERVER_HEADER_VALUE);
-    res.headers_mut().append(CONTENT_TYPE, JSON_HEADER_VALUE);
-
-    Ok(res)
+async fn updates(
+    StateRef(pool): StateRef<'_, DieselPool>,
+    UriRef(uri): UriRef<'_>,
+) -> Result<Json<impl Serialize>, Error> {
+    let num = uri.query().parse_query();
+    let worlds = pool.update(num).await?;
+    Ok(Json(worlds))
 }

+ 2 - 84
frameworks/Rust/xitca-web/src/util.rs

@@ -1,44 +1,8 @@
 #![allow(clippy::declare_interior_mutable_const)]
 
-use std::{
-    cell::{RefCell, RefMut},
-    cmp,
-    convert::Infallible,
-    io,
-};
+use std::cmp;
 
-use xitca_web::{
-    dev::bytes::{Bytes, BytesMut},
-    http::{
-        header::{HeaderValue, SERVER},
-        StatusCode,
-    },
-    response::{WebResponse, WebResponseBuilder},
-};
-
-pub(super) type HandleResult = Result<WebResponse, Infallible>;
-
-pub(super) struct Writer<'a>(RefMut<'a, BytesMut>);
-
-impl Writer<'_> {
-    #[inline]
-    pub fn take(mut self) -> Bytes {
-        self.0.split().freeze()
-    }
-}
-
-impl io::Write for &mut Writer<'_> {
-    #[inline]
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.0.extend_from_slice(buf);
-        Ok(buf.len())
-    }
-
-    #[inline]
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
+use xitca_http::http::header::HeaderValue;
 
 pub(super) trait QueryParse {
     fn parse_query(self) -> u16;
@@ -58,50 +22,4 @@ impl QueryParse for Option<&str> {
     }
 }
 
-pub(super) struct AppState<C> {
-    client: C,
-    // a re-usable buffer for write response data.
-    write_buf: RefCell<BytesMut>,
-}
-
-impl<C> AppState<C> {
-    pub(super) fn new(client: C) -> Self {
-        let write_buf = RefCell::new(BytesMut::new());
-        Self { client, write_buf }
-    }
-
-    #[inline]
-    pub(super) fn writer(&self) -> Writer<'_> {
-        Writer(self.write_buf.borrow_mut())
-    }
-
-    #[inline]
-    pub(super) fn client(&self) -> &C {
-        &self.client
-    }
-}
-
 pub const SERVER_HEADER_VALUE: HeaderValue = HeaderValue::from_static("TFB");
-
-pub const HTML_HEADER_VALUE: HeaderValue = HeaderValue::from_static("text/html; charset=utf-8");
-
-pub const TEXT_HEADER_VALUE: HeaderValue = HeaderValue::from_static("text/plain");
-
-pub const JSON_HEADER_VALUE: HeaderValue = HeaderValue::from_static("application/json");
-
-macro_rules! error {
-    ($error: ident, $code: path) => {
-        #[cold]
-        #[inline(never)]
-        pub(super) fn $error() -> HandleResult {
-            Ok(WebResponseBuilder::new()
-                .status($code)
-                .header(SERVER, SERVER_HEADER_VALUE)
-                .body(Bytes::new().into())
-                .unwrap())
-        }
-    };
-}
-
-error!(not_found, StatusCode::NOT_FOUND);
-error!(internal, StatusCode::INTERNAL_SERVER_ERROR);

+ 2 - 2
frameworks/Rust/xitca-web/xitca-web-diesel.dockerfile

@@ -1,9 +1,9 @@
-FROM rust:1.59
+FROM rust:1.60
 
 ADD ./ /xitca-web
 WORKDIR /xitca-web
 
-RUN rustup default nightly-2022-03-24
+RUN rustup default nightly-2022-04-27
 RUN cargo clean
 RUN RUSTFLAGS="-C target-cpu=native" cargo build --release --bin xitca-web-diesel
 

+ 2 - 2
frameworks/Rust/xitca-web/xitca-web.dockerfile

@@ -1,9 +1,9 @@
-FROM rust:1.59
+FROM rust:1.60
 
 ADD ./ /xitca-web
 WORKDIR /xitca-web
 
-RUN rustup default nightly-2022-03-24
+RUN rustup default nightly-2022-04-27
 RUN cargo clean
 RUN RUSTFLAGS="-C target-cpu=native" cargo build --release --bin xitca-web