Rust
chunk-engine (rs-chunks) in Axum, Actix Web, Rocket, and Warp.
Read the uploaded bytes and call
get_chunks_from_bytes(&data, filename, mode, window_size, overlap, sentences_per_chunk, paragraphs_per_page). The import name is chunks_rs; every
chunk is Chunk { content, content_type, metadata } where metadata is a
serde_json::Value.
Handlers are illustrative
Error handling is unwrapped for brevity — return a Result / proper status in
production. filename only needs the correct extension so the engine can
dispatch.
Axum
use axum::{extract::Multipart, Json};
use chunks_rs::get_chunks_from_bytes;
use serde_json::{json, Value};
async fn chunk(mut multipart: Multipart) -> Json<Value> {
let field = multipart.next_field().await.unwrap().unwrap();
let filename = field.file_name().unwrap_or("upload").to_string();
let data = field.bytes().await.unwrap();
let chunks = get_chunks_from_bytes(&data, &filename, "default", 3, 1, 3, 15).unwrap();
Json(json!({ "count": chunks.len() }))
}Actix Web
use actix_multipart::Multipart;
use actix_web::{post, HttpResponse, Responder};
use futures_util::StreamExt;
use chunks_rs::get_chunks_from_bytes;
#[post("/chunk")]
async fn chunk(mut payload: Multipart) -> impl Responder {
while let Some(Ok(mut field)) = payload.next().await {
let filename = field
.content_disposition()
.and_then(|cd| cd.get_filename())
.unwrap_or("upload")
.to_string();
let mut bytes = Vec::new();
while let Some(Ok(chunk)) = field.next().await {
bytes.extend_from_slice(&chunk);
}
let chunks = get_chunks_from_bytes(&bytes, &filename, "default", 3, 1, 3, 15).unwrap();
return HttpResponse::Ok().json(serde_json::json!({ "count": chunks.len() }));
}
HttpResponse::BadRequest().finish()
}Rocket
Rocket's TempFile is already on disk, so dispatch by path — keep the original
extension so routing works:
#[macro_use] extern crate rocket;
use rocket::form::Form;
use rocket::fs::TempFile;
use rocket::serde::json::{json, Value};
use chunks_rs::get_chunks;
#[derive(FromForm)]
struct Upload<'r> {
document: TempFile<'r>,
}
#[post("/chunk", data = "<form>")]
async fn chunk(mut form: Form<Upload<'_>>) -> Value {
let name = form.document.raw_name()
.map(|n| n.dangerous_unsafe_unsanitized_raw().as_str().to_string())
.unwrap_or_else(|| "upload.bin".into());
let path = std::env::temp_dir().join(name);
form.document.persist_to(&path).await.unwrap();
let chunks = get_chunks(path.to_str().unwrap(), "default", 3, 1, 3, 15).unwrap();
json!({ "count": chunks.len() })
}Warp
Warp's multipart is verbose; the cleanest route is a raw body plus a filename
header (send X-Filename: report.docx from the client):
use warp::Filter;
use chunks_rs::get_chunks_from_bytes;
let chunk = warp::post()
.and(warp::path("chunk"))
.and(warp::header::<String>("x-filename"))
.and(warp::body::bytes())
.map(|filename: String, body: bytes::Bytes| {
let chunks =
get_chunks_from_bytes(&body, &filename, "default", 3, 1, 3, 15).unwrap();
warp::reply::json(&serde_json::json!({ "count": chunks.len() }))
});Per-format entry points
For a single known format you can skip source detection and call the family
module directly — e.g. chunks_rs::formats::docx::chunk_from_bytes(...). Each
chunks_rs::formats::* module also exposes stream(...), to_markdown, and
(where applicable) *_with_images. See the API Reference.